jest.toThrow unable to catch exception?

I have a simple function as below

function foo({ platform }) {
  if (platform === 'all') {
    throw new Error('Platform value can only be android or ios');
  }
  
  return `${platform}`;
}

Then I wrote unit testing as below

it('should return correct result with platform', () => {
    expect(foo({ platform: 'ios' })).toBe('ios');
    expect(foo({ platform: 'android' })).toBe('android');
    expect(foo({platform: 'all'})).toThrow(new Error('Platform value can only be android or ios'));
  });

The test actually failed due to last test case without any useful information

 FAIL  src/utils/__test__/foo.test.ts
  ● foo() › should return correct result with platform

    Platform value can only be android or ios

      16 | }) {
      17 |   if (platform === 'all') {
    > 18 |     throw new Error('Platform value can only be android or ios');
         |           ^
      19 |   }
      20 |   
      21 |   return `${platform}`;

      at xx (src/utils/foo.ts:18:11)

I’ve also tried to wrapped the entire expect with try catch block but the test is not passing either

Javascript functions are cutting in and out

I have one issue that is a recurring thing every time I work in Javascript, which is that my code seems to be cutting in and out, depending on whether I scroll, resize the screen, reload, etc. It even seems like the speed of which I scroll seems to be a factor (even though I am, in this situation, trying to create a scroll effect, which does work as long as I scroll slowly). I have tried to figure out work arounds almost constantly since starting coding JS, but I can’t even figure out why any of this is happening, and I don’t even know what to good to find the answers.

Generally, when I create functions, I try to use the following structure

document.addEventListener("click", function(functionName) { function content });

However, this really only seems to work with click effects, and maybe hover. for scroll effects, because resizing the screen will cause weird things to happen, I have tried using the following structure

function functionName() { function content };

document.addEventListener('scroll', functionName);
window.addEventListener('load', functionName);
window.addEventListener('resize', functionName); 

This generally works better, and generally prevents screen resizing from interfering too much with scroll effects. However, it makes the code what I am seeing very jumpy and glitchy.

Is there a better way to do this, so that I am a scroll effect will always appear how it should, regardless of whether the screen resizes loads or scrolls, etc.? also, it there a way to make the code work better without having three separate event listeners to activate a single function?

Map an array, but place X amount of items each pass

Sorry if this has been answered before- didn’t even know how to correctly google it.

I’m creating a grid of client logos using Tailwind, react, and GSAP. Client logo paths are loaded in via a json file. The client logo list is pretty long, so I thought it would be interesting to have the images in each grid col-spans (‘cells’) fade to a different image every few seconds.

My solution thus far is to map through all the logos and stack a certain number of them on top of each other as absolute before moving onto the next col span and then animate them in and out using the ids of the col-spans. I’m having trouble wrapping my mind around the approach. Especially with responsibly changing the grid-cols.

The approach so far (some pseudo-code some irl code):

const maxCols = 4
const maxRows = 3
const itemsPerRow = Math.floor( logosList.length()/maxCols/maxRows)
const isExtra = () =>{
     if(logosList.length() % itemsPerRow >0) return true
     else return false
}
const numRows = Math.floor( logosList.length()/maxCols )



export default function ClientImages(){
     useEffect(() => {
          for(i = 0; i <= i/maxCols/maxRows; i++  )
               // to be figured out gsap method
               gsap.to(`img-${i}`, {animate stuff})
     },);
     
     function setLogos(){
          let subset
          for ( index = 0; index == maxCols * maxRows; index++ ){
               if(isExtra){
                    subset = logosList.slice(index, itemsPerRow + 1) 
               }
               else subset = logosList.slice(index, itemsPerRow) 
               return(
                    <div className="col-span-1 relative" id={`clientColSpan-${index}`}>
                    {subset.map((logo) => {
                         <Image className='absolute' src={logo.src} yada yada yada />
                    })}
                    </div>
               )
          }
          
     }
     return(
          <div className="grid grid-cols-2 md:grid-cols-4 2xl:grid-cols-6">
               {setLogos}
          </div>
     )

}

Here’s a visual representation of my thought process

Mobile Breakpoints

Desktop Breakpoints

How do I detect value changes of input tags with different ids?

I’m currently working with a flowchart libray called flowy and it has functions that detect value changes of a block everytime the user types in text and save it as json.However, when I added some input tags to get more than a pair of values named key&content and tried to save these input values, only the first pair of key&content were stored in the output. I want to know how to save multiple input values with different ids.

added input values

flowy code

document.addEventListener("DOMContentLoaded", function(){
let rightcard = false;
let tempblock;
let tempblock2;
//document.getElementById("blocklist").innerHTML = '<div class="blockelem create-flowy noselect"><input type="hidden" name="blockelemtype" class="blockelemtype" value="1"><div class="grabme"><img src="/resources/flowy/assets/grabme.svg"></div><div class="blockin">                  <div class="blockico"><span></span><img src="/resources/flowy/assets/eye.svg"></div><div class="blocktext">                        <p class="blocktitle">New visitor</p><p class="blockdesc">Triggers when somebody visits a specified page</p>        </div></div></div><div class="blockelem create-flowy noselect"><input type="hidden" name="blockelemtype" class="blockelemtype" value="2"><div class="grabme"><img src="/resources/flowy/assets/grabme.svg"></div><div class="blockin">                    <div class="blockico"><span></span><img src="/resources/flowy/assets/action.svg"></div><div class="blocktext">                        <p class="blocktitle">Action is performed</p><p class="blockdesc">Triggers when somebody performs a specified action</p></div></div></div><div class="blockelem create-flowy noselect"><input type="hidden" name="blockelemtype" class="blockelemtype" value="3"><div class="grabme"><img src="/resources/flowy/assets/grabme.svg"></div><div class="blockin">                    <div class="blockico"><span></span><img src="/resources/flowy/assets/time.svg"></div><div class="blocktext">                        <p class="blocktitle">Time has passed</p><p class="blockdesc">Triggers after a specified amount of time</p>          </div></div></div><div class="blockelem create-flowy noselect"><input type="hidden" name="blockelemtype" class="blockelemtype" value="4"><div class="grabme"><img src="/resources/flowy/assets/grabme.svg"></div><div class="blockin">                    <div class="blockico"><span></span><img src="/resources/flowy/assets/error.svg"></div><div class="blocktext">                        <p class="blocktitle">Error prompt</p><p class="blockdesc">Triggers when a specified error happens</p>              </div></div></div>';
flowy(document.getElementById("canvas"), drag, release, snapping);
function addEventListenerMulti(type, listener, capture, selector) {
    var nodes = document.querySelectorAll(selector);
    for (var i = 0; i < nodes.length; i++) {
        nodes[i].addEventListener(type, listener, capture);
    }
}
function snapping(drag, first) {
    var grab = drag.querySelector(".grabme");
    grab.parentNode.removeChild(grab);
    var blockin = drag.querySelector(".blockin");
    blockin.parentNode.removeChild(blockin);
    if (drag.querySelector(".blockelemtype").value == "1") {
        drag.innerHTML += "<input type='hidden' name='sceneId' /><input type='hidden' name='inputValues' /><input type='hidden' name='outputMessage' /><input type='hidden' name='maxRepeatNumber' /><div class='blockyleft'><img src='/resources/flowy/assets/twitterorang.svg'><p class='blockyname'>Basic</p><p class='scene-input-values'></p></div><div class='blockyright'><img src='/resources/flowy/assets/more.svg'></div><div class='blockydiv'></div><div class='blockyinfo'><span class=' scene-output-message'></span></div>";
    } else if (drag.querySelector(".blockelemtype").value == "c") {
        drag.innerHTML += "<input type='hidden' name='sceneId' /><input type='hidden' name='inputValues' /><input type='hidden' name='outputMessage' /><input type='hidden' name='maxRepeatNumber' /><div class='blockyleft'><img src='/resources/flowy/assets/twitterorange.svg'><p class='blockyname'>Basic Input</p><p class='scene-input-values'></p></div><div class='blockyright'><img src='/resources/flowy/assets/more.svg'></div><div class='blockydiv'></div><div class='blockyinfo'><span class=' scene-output-message'></span></div>";
    } else if (drag.querySelector(".blockelemtype").value == "f") {
        drag.innerHTML += "<input type='hidden' name='sceneId' /><input type='hidden' name='inputValues' /><input type='hidden' name='outputMessage' /><input type='hidden' name='maxRepeatNumber' /><div class='blockyleft'><img src='/resources/flowy/assets/twitterorange.svg'><p class='blockyname'>Text Input</p><p class='scene-input-values'></p></div><div class='blockyright'><img src='/resources/flowy/assets/more.svg'></div><div class='blockydiv'></div><div class='blockyinfo'><span class=' scene-output-message'></span></div>";
    } else if (drag.querySelector(".blockelemtype").value == "m") {
        drag.innerHTML += "<input type='hidden' name='sceneId' /><input type='hidden' name='inputValues' /><input type='hidden' name='outputMessage' /><input type='hidden' name='maxRepeatNumber' /><div class='blockyleft'><img src='/resources/flowy/assets/twitterorange.svg'><p class='blockyname'>Message</p><p class='scene-input-values'></p></div><div class='blockyright'><img src='/resources/flowy/assets/more.svg'></div><div class='blockydiv'></div><div class='blockyinfo'><span class=' scene-output-message'></span></div>";
    } else if (drag.querySelector(".blockelemtype").value == "t") {
        drag.innerHTML += "<input type='hidden' name='sceneId' /><input type='hidden' name='inputValues' /><input type='hidden' name='outputMessage' /><input type='hidden' name='maxRepeatNumber' /><div class='blockyleft'><img src='/resources/flowy/assets/timeblue.svg'><p class='blockyname'>Timeout for input</p></div><div class='blockyright'><img src='/resources/flowy/assets/more.svg'></div><div class='blockydiv'></div><div class='blockyinfo'><span class=' scene-output-message'></span></div>";
    } else if (drag.querySelector(".blockelemtype").value == "r") {
        drag.innerHTML += "<input type='hidden' name='sceneId' /><input type='hidden' name='inputValues' /><input type='hidden' name='outputMessage' /><input type='hidden' name='maxRepeatNumber' /><div class='blockyleft'><img src='/resources/flowy/assets/actionblue.svg'><p class='blockyname'>Request a call</p></div><div class='blockyright'><img src='/resources/flowy/assets/more.svg'></div><div class='blockydiv'></div><div class='blockyinfo'><span class=' scene-output-message'></span></div>";
    } else if (drag.querySelector(".blockelemtype").value == "g") {
        drag.innerHTML += "<input type='hidden' name='sceneId' /><input type='hidden' name='inputValues' /><input type='hidden' name='outputMessage' /><input type='hidden' name='maxRepeatNumber' /><input type='hidden' name='toChapterId' /><div class='blockyleft'><img src='/resources/flowy/assets/actionblue.svg'><p class='blockyname'>Go to Chapter</p></div><div class='blockyright'><img src='/resources/flowy/assets/more.svg'></div><div class='blockydiv'></div><div class='blockyinfo'><span class=' scene-output-message'></span><span class=' scene-go-to-chapter'></span></div>";
    } else if (drag.querySelector(".blockelemtype").value == "n") {
        drag.innerHTML += "<input type='hidden' name='sceneId' /><input type='hidden' name='inputValues' /><input type='hidden' name='outputMessage' /><input type='hidden' name='maxRepeatNumber' /><input type='hidden' name='toSceneId' /><div class='blockyleft'><img src='/resources/flowy/assets/actionblue.svg'><p class='blockyname'>Go to Scene</p></div><div class='blockyright'><img src='/resources/flowy/assets/more.svg'></div><div class='blockydiv'></div><div class='blockyinfo'><span class=' scene-output-message'></span><span class=' scene-go-to-scene'></span></div>";
    } else if (drag.querySelector(".blockelemtype").value == "w") {
        drag.innerHTML += "<input type='hidden' name='sceneId' /><input type='hidden' name='inputValues' /><input type='hidden' name='outputMessage' /><input type='hidden' name='maxRepeatNumber' /><div class='blockyleft'><img src='/resources/flowy/assets/errorred.svg'><p class='blockyname'>Wrong input</p></div><div class='blockyright'><img src='/resources/flowy/assets/more.svg'></div><div class='blockydiv'></div><div class='blockyinfo'><span class=' scene-output-message'></span></div>";
    }

    $(drag).find('input[name=inputValues]').change(function() {
        $(drag).find('.scene-input-values').html($(this).val());
    });
    $(drag).find('input[name=outputMessage]').change(function() {
        $(drag).find('.chapter-message').html($(this).val());
    });

    $(drag).find('input[name=toChapterId]').change(function() {
        $(drag).find('.chapter-message').html($(this).val());
    });
    return true;
}
function drag(block) {
    block.classList.add("blockdisabled");
    tempblock2 = block;
}
function release() {
    if (tempblock2) {
        tempblock2.classList.remove("blockdisabled");
    }
}
let disabledClick = function(){
    document.querySelector(".navactive").classList.add("navdisabled");
    document.querySelector(".navactive").classList.remove("navactive");
    this.classList.add("navactive");
    this.classList.remove("navdisabled");
    if (this.getAttribute("id") == "triggers") {
        document.getElementById("blocklist").innerHTML = '<div class="blockelem create-flowy noselect"><input type="hidden" name="blockelemtype" class="blockelemtype" value="1"><div class="grabme"><img src="/resources/flowy/assets/grabme.svg"></div><div class="blockin">                  <div class="blockico"><span></span><img src="/resources/flowy/assets/eye.svg"></div><div class="blocktext">                        <p class="blocktitle">New visitor</p><p class="blockdesc">Triggers when somebody visits a specified page</p>        </div></div></div><div class="blockelem create-flowy noselect"><input type="hidden" name="blockelemtype" class="blockelemtype" value="2"><div class="grabme"><img src="/resources/flowy/assets/grabme.svg"></div><div class="blockin">                    <div class="blockico"><span></span><img src="/resources/flowy/assets/action.svg"></div><div class="blocktext">                        <p class="blocktitle">Action is performed</p><p class="blockdesc">Triggers when somebody performs a specified action</p></div></div></div><div class="blockelem create-flowy noselect"><input type="hidden" name="blockelemtype" class="blockelemtype" value="3"><div class="grabme"><img src="/resources/flowy/assets/grabme.svg"></div><div class="blockin">                    <div class="blockico"><span></span><img src="/resources/flowy/assets/time.svg"></div><div class="blocktext">                        <p class="blocktitle">Time has passed</p><p class="blockdesc">Triggers after a specified amount of time</p>          </div></div></div><div class="blockelem create-flowy noselect"><input type="hidden" name="blockelemtype" class="blockelemtype" value="4"><div class="grabme"><img src="/resources/flowy/assets/grabme.svg"></div><div class="blockin">                    <div class="blockico"><span></span><img src="/resources/flowy/assets/error.svg"></div><div class="blocktext">                        <p class="blocktitle">Error prompt</p><p class="blockdesc">Triggers when a specified error happens</p>              </div></div></div>';
    } else if (this.getAttribute("id") == "actions") {
        document.getElementById("blocklist").innerHTML = '<div class="blockelem create-flowy noselect"><input type="hidden" name="blockelemtype" class="blockelemtype" value="5"><div class="grabme"><img src="/resources/flowy/assets/grabme.svg"></div><div class="blockin">                  <div class="blockico"><span></span><img src="/resources/flowy/assets/database.svg"></div><div class="blocktext">                        <p class="blocktitle">New database entry</p><p class="blockdesc">Adds a new entry to a specified database</p>        </div></div></div><div class="blockelem create-flowy noselect"><input type="hidden" name="blockelemtype" class="blockelemtype" value="6"><div class="grabme"><img src="/resources/flowy/assets/grabme.svg"></div><div class="blockin">                  <div class="blockico"><span></span><img src="/resources/flowy/assets/database.svg"></div><div class="blocktext">                        <p class="blocktitle">Update database</p><p class="blockdesc">Edits and deletes database entries and properties</p>        </div></div></div><div class="blockelem create-flowy noselect"><input type="hidden" name="blockelemtype" class="blockelemtype" value="7"><div class="grabme"><img src="/resources/flowy/assets/grabme.svg"></div><div class="blockin">                  <div class="blockico"><span></span><img src="/resources/flowy/assets/action.svg"></div><div class="blocktext">                        <p class="blocktitle">Perform an action</p><p class="blockdesc">Performs or edits a specified action</p>        </div></div></div><div class="blockelem create-flowy noselect"><input type="hidden" name="blockelemtype" class="blockelemtype" value="8"><div class="grabme"><img src="/resources/flowy/assets/grabme.svg"></div><div class="blockin">                  <div class="blockico"><span></span><img src="/resources/flowy/assets/twitter.svg"></div><div class="blocktext">                        <p class="blocktitle">Make a tweet</p><p class="blockdesc">Makes a tweet with a specified query</p>        </div></div></div>';
    } else if (this.getAttribute("id") == "loggers") {
        document.getElementById("blocklist").innerHTML = '<div class="blockelem create-flowy noselect"><input type="hidden" name="blockelemtype" class="blockelemtype" value="9"><div class="grabme"><img src="/resources/flowy/assets/grabme.svg"></div><div class="blockin">                  <div class="blockico"><span></span><img src="/resources/flowy/assets/log.svg"></div><div class="blocktext">                        <p class="blocktitle">Add new log entry</p><p class="blockdesc">Adds a new log entry to this project</p>        </div></div></div><div class="blockelem create-flowy noselect"><input type="hidden" name="blockelemtype" class="blockelemtype" value="10"><div class="grabme"><img src="/resources/flowy/assets/grabme.svg"></div><div class="blockin">                  <div class="blockico"><span></span><img src="/resources/flowy/assets/log.svg"></div><div class="blocktext">                        <p class="blocktitle">Update logs</p><p class="blockdesc">Edits and deletes log entries in this project</p>        </div></div></div><div class="blockelem create-flowy noselect"><input type="hidden" name="blockelemtype" class="blockelemtype" value="11"><div class="grabme"><img src="/resources/flowy/assets/grabme.svg"></div><div class="blockin">                  <div class="blockico"><span></span><img src="/resources/flowy/assets/error.svg"></div><div class="blocktext">                        <p class="blocktitle">Prompt an error</p><p class="blockdesc">Triggers a specified error</p>        </div></div></div>';
    }
}
addEventListenerMulti("click", disabledClick, false, ".side");
document.getElementById("close").addEventListener("click", function(){
   if (rightcard) {
       rightcard = false;
       document.getElementById("properties").classList.remove("expanded");
       document.getElementById("propwrap").classList.remove("itson");
       tempblock.classList.remove("selectedblock");
   }
});

document.getElementById("removeblock").addEventListener("click", function(){
    flowy.deleteBlocks();
});
let aclick = false;
let noinfo = false;
let beginTouch = function (event) {
    aclick = true;
    noinfo = false;

    if (event.target.closest(".create-flowy")) {
        noinfo = true;
    }
    if ( event.target.closest("#propwrap")) {

    } else {
        if ( tempblock != undefined ) {
            tempblock.classList.remove("selectedblock");
        }
        document.getElementById("properties").classList.remove("expanded");
        document.getElementById("propwrap").classList.remove("itson");
    }
}
let checkTouch = function (event) {
    aclick = false;
}
let doneTouch = function (event) {
    if (event.type === "mouseup" && aclick && !noinfo) {
        if (event.target.closest(".block") && !event.target.closest(".block").classList.contains("dragging")) {
            tempblock = event.target.closest(".block");
            rightcard = true;
            document.getElementById("properties").classList.add("expanded");
            document.getElementById("propwrap").classList.add("itson");
            tempblock.classList.add("selectedblock");

            let tempInputValue = $(tempblock).find('input[name=inputValues]').val();
            let tempMessage = $(tempblock).find('input[name=outputMessage]').val();
            let tempToChapterId = $(tempblock).find('input[name=toChapterId]').val();
            let tempMaxRepeatNumber = $(tempblock).find('input[name=maxRepeatNumber]').val();
            //$('#form-scene-input-value').val($(tempblock).find('.blockyname').html());


            if ( $(tempblock).find('input[name=blockelemtype]').val() == 'g' ) {
                $('.form-group-go-to-chapter').show();
                $('#form-go-to-chapter').val(tempToChapterId);
                $('.form-group-max-repeat-number').hide();
                $('.form-group-output-message').hide();
                $('.form-group-input-value').hide();
                $('#form-scene-input-value').tagsinput('removeAll');
            } else if ( $(tempblock).find('input[name=blockelemtype]').val() == 'm' ) {
                $('.form-group-go-to-chapter').hide();
                $('.form-group-max-repeat-number').hide();
                $('.form-group-output-message').show();
                $('.form-group-input-value').hide();
                $('#form-scene-input-value').tagsinput('removeAll');
            } else if ( $(tempblock).find('input[name=blockelemtype]').val() == 't'
                        || $(tempblock).find('input[name=blockelemtype]').val() == 'w' ) {
                $('.form-group-go-to-chapter').hide();
                $('.form-group-max-repeat-number').show();
                $('#form-max-repeat-number').val(tempMaxRepeatNumber);
                $('.form-group-output-message').show();
                $('#form-output-message').val(tempMessage);
                $('.form-group-input-value').hide();
                $('#form-scene-input-value').tagsinput('removeAll');
            }else {
                $('.form-group-go-to-chapter').hide();
                $('.form-group-max-repeat-number').hide();
                $('.form-group-output-message').show();
                $('#form-output-message').val(tempMessage);
                $('.form-group-input-value').show();
                $('#form-scene-input-value').tagsinput('removeAll');
                $('#form-scene-input-value').tagsinput('add',tempInputValue);

            }
       }
    }
}
addEventListener("mousedown", beginTouch, false);
addEventListener("mousemove", checkTouch, false);
addEventListener("mouseup", doneTouch, false);
addEventListenerMulti("touchstart", beginTouch, false, ".block");

saveChapter = function() {
    let id = $('#form-chapter-id').val();
    let title = $('#form-chapter-title').val();
    let memberGroup = $('#form-chapter-member_group').val();
    let schedule = $('#form-schedule').val();
    let timeout = $('#form-timeout').val();

        let data = {
            id: id,
            title: title,
            chapter: JSON.stringify(flowy.output()),
            memberGroup: memberGroup,
            schedule: schedule,
            timeout: timeout
        };

        $.ajax("ajax/do-save", {
            data: data,
            dataType: "json",
            method: "POST",
            async: true,
            success: function (resultData) {
                if (resultData.result == 'true') {
                    $('#form-chapter-id').val(resultData.id);
                    window.close();
                    window.opener.location.reload();
                } else {
                    alert('aa.');
                }

            }
        });


    }


}


$('#form-scene-input-value').change(function() {
    $(tempblock).find('.scene-input-values').html($(this).val());
    $(tempblock).find('input[name=inputValues]').val($(this).val());
});

$('#form-output-message').keyup(function() {
    $(tempblock).find('.scene-output-message').html($(this).val());
    $(tempblock).find('input[name=outputMessage]').val($(this).val());
});

$('#form-go-to-chapter').change(function() {
    $(tempblock).find('.scene-go-to-chapter').html($('#form-go-to-chapter option:checked').text());
    $(tempblock).find('input[name=toChapterId]').val($(this).val());
});

$('#form-max-repeat-number').change(function() {
    $(tempblock).find('input[name=maxRepeatNumber]').val($(this).val());
});

if ( chapterData != null ) {
    flowy.import(chapterData);
}

});

html code

<div class="form-group form-group-extraData" id="box">
<input type="text" class="form-control" id="form-key1" name="key" placeholder="key" autocomplete="off" value="" >
<input type="text" class="form-control" id="form-content1" name="content" placeholder="content" autocomplete="off" value="">
<input type="button" class="btn btn-alt-primary" value="+" onclick="addTextbox()" >

How to send canvas as a image/png in nodejs exress

Basicly i want to make all my assets in the backend
i did some testing and tried the canvas npm package
in the docs it said to do '<img src="' + canvas.toDataUrl() + '">'
but that sends a html document i want to just send a image like .png

code:

const express = require('express');
const { createCanvas, loadImage } = require('canvas')
const moment = require('moment')
const { getCard} = require('./cards.js')
const path = require('path')
require('colors')


const app = express();
const port = process.env.PORT || 3001;

app.use('/assets', express.static(path.join(__dirname, './assets')))


app.get('/cards', (req, res) => {
    res.send(getCard())
})

app.get('/hand', (req, res) => {
    const hand = [
        getCard(),
        getCard(),
        getCard(),
    ]
    res.send(hand)
})

app.get('/cards/getSprite/:type/:color/:number', (req, res) => {
    const canvas = createCanvas(200, 100)
    const ctx = canvas.getContext('2d') 

    const type = req.params.type
    const color = req.params.color
    const number = req.params.number


    ctx.font = '30px Impact'
    
    ctx.fillText(type , 50, 100)
    ctx.fillText(number , 50, 200)

    const params = {
        type: type,
        color: color,
        number: number
    }

    res.send(canvas.toDataURL('image/png'))

})

app.listen(port, () => {
    console.log('[Backend] '.blue + '[Listening]'.red + `: Backend listening on http://localhost:${port} at ${moment().format('MMMM Do YYYY, h:mm:ss a')}`)
});

is there any possible way without hardcoding the assets

getJSON doesn’t find local file

I have a function that is calling getJSON to retrieve a local file, but it doesn’t work.

The function is:

function login(email, password) {
    console.log('in login');
    $.getJSON("./config.json", function(config) {
        console.log('in getJSON, config = ', config);
    });
    console.log('aft getJSON');
}

The message stack is:

in login
aft getJSON

As you can see, the process flow doesn’t get into the callback function and I can’t figure out why, as the file definitely exists.

Can anyone give me some ideas why getJSON doesn’t appear to be finding the file or maybe another reason why it isn’t working or a better way to read a local file?

Making a counter using JavaScript/JQuery clone method in an HTML table

I need to make a counter using JavaScript/JQuery with clone method in the second column like for example the first row 1 and when I click on add button it automatically display number 2. I am using clone method in JavaScript/JQuery and I don’t know how to add this. This is my full code:

var cloned = $('#myTable tr:last').clone();
$(".add-row").click(function(e) {
  e.preventDefault();
  cloned.clone().appendTo('#myTable');
});

$('#myTable').on('click', ".delete-row", function(e) {
  e.preventDefault();
  $(this).closest('tr').remove();
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table table-bordered table-hover table-striped table-sm" id="myTable">
  <thead>
    <th></th>
    <th>#</th>
    <th>test1</th>
    <th>test2</th>
    <th>test3</th>
    <th>test4</th>
    <th>test5</th>
  </thead>
  <tbody>
    <tr>
      <td>
        <a href="#" class="btn btn-sm btn-danger delete-row">delete</a>
      </td>
      <td>
      <!-- Counter here -->
      </td>
    </tr>
  </tbody>
</table>
<a href="#" class="btn btn-sm btn-primary add-row">add</a>

Python’s zlib decompresses data, but Pako (JavaScript zlib) fails

I’m trying to inflate some zlib compressed data (Ren’Py Archive 3 archive file structure for those wondering) with JavaScript, but I can’t seem to reproduce the Python behavior in Node.js.

This Python script works:

import zlib

# Data written to a file from a different Python script, for demo purposes
# This would be a value in memory in JS
data = open("py", "rb")

# Works
print(
    zlib.decompress(data.read(), 0)
)

While this Node.js script:

const fs = require('fs');
const pako = require('pako');

const data = fs.readFileSync('py', 'binary');

// Doesn't work
console.log(
    pako.inflateRaw(data)
);

Throws this error:

C:UsersgunneDocumentsProgrammingnode.jsrpa-extractornode_modulespakolibinflate.js:384
  if (inflator.err) throw inflator.msg || msg[inflator.err];
                    ^
invalid stored block lengths
(Use `node --trace-uncaught ...` to show where the exception was thrown)

As per the Python zlib.decompress documentation, a wbits parameter (the second parameter) of 0 “automatically [determines] the window size from the zlib header,” something that the Pako implementation seemingly doesn’t do.

Am I doing something incorrectly? How would I achieve the same output as in Python using Node.js?

Possible optimizations for my alpha-beta pruning algorithm?

I’m a new programmer currently coding a javascript alpha-beta pruning minimax algorithm for my chess engine. I’ve implemented a basic algorithm with move ordering, and instead of evaluating each leaf node I’m “tracking” each move made along the way as to speed up the board evaluation. Currently, it’s evaluating around 14000 nodes for 8 seconds, which is way too slow. Is there something wrong with my algorithm or are there optimizations that I can implement? I was also thinking about making each branch search asynchronously, i.e. each of the x possible moves will run at the same time and compare the results when all branches have finished evaluating. Thank you.

function minimax(game, depth, distanceFromRoot, alpha, beta, gameEval) {//returns gameEval
    if (depth === 0) {
      nodeNum++;
      if(game.turn() === 'b'){
        return (-gameEval / 8);
      }else{
        return (gameEval / 8);
      }
    }

    // run eval 
    var prevEval = gameEval;

    var moves = game.moves();
    moveOrdering(moves);
    var bestMove = null;
    var bestEval = null;
    for (let i = 0; i < moves.length; i++) {
      var gameCopy = new Chess()//dummy board to pass down
      gameCopy.load(game.fen())
      const moveInfo = gameCopy.move(moves[i])

      var curGameCopy = new Chess()//static board to eval, before the move so we know which piece was taken if a capture occurs
      curGameCopy.load(game.fen())
      var curEval = trackingEval(curGameCopy, prevEval, moveInfo, moves[i]); //returns the OBJECTIVE eval for the current move for current move sequence
      var evaluated = -minimax(gameCopy, depth - 1, distanceFromRoot + 1, -beta, -alpha, curEval);//pass down the current eval for that move
      if (evaluated >= beta) {
        return beta;
      }

      if (evaluated > alpha){
        alpha = evaluated
        bestMove = moves[i]
        bestEval = evaluated;
        if (distanceFromRoot === 0) {
          bestEval = evaluated;
        }
      }
    }
    
    if(distanceFromRoot === 0){
      setEval(-bestEval)
      return bestMove;
    }
    return alpha;
  }

How does one pass an array with no fixed size into the vertex shader?

I have an array with no fixed size (let noise = [];) in my .js file where it stores the noise values for a point (noise[i] -> a single point).

I was wondering if I’m able to pass all the values inside the array into my vertex.shader by doing:

//.js
for(let i = 0; i < noise.length; i++) {
    const uNoise = gl.getUniformLocation(program, "uNoise[" + i + "]");
    gl.uniform3fv(uNoise, MV.flatten(noise[i]));
}

//vertex.shader
let uNoise[];

If not, how would it possible to do it?

isAuth is not defined

i defined isAuth in Line 14 but i got error “srcApp.js
Line 25:13: ‘isAuth’ is not defined no-undef”
idk, maybe i defined it wrong, looking up for your help, thanks

import React, { Component } from 'react';
import './css/main.css';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
import Home from './pages/Home';
import CreatePost from './pages/CreatePost';
import Login from './pages/Login';


class App extends Component {

  constructor(props) {
    super(props);
    this.state = {
      isAuth: false,
      setIsAuth: false
    };
  }

  render() {
    return (
      <Router>
        <nav>
          <Link to="/">Home</Link>
          <Link to="/createpost"> Create New Post</Link>
          {!isAuth && <Link to="/login">Login</Link>}
        </nav>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/login" element={<Login setIsAuth={this.state.setIsAuth} />} />
          <Route path="/createpost" element={<CreatePost />} />
        </Routes>
      </Router>
    );
  }
}

export default App;

How to find whether time ranges overlap?

I have the following time ranges 1pm to 3pm and 9am to 5pm. I know a doctor is available between 9am and 5pm. The patient is looking for doctors that are available from 1pm to 3pm. When he inputs that time range, he should be able to see the doctor in the list. For example, if the doctor is available from 9am to 12pm, and the patient input 3pm to 5pm, the doctor won’t show up. I’m trying to match doctors with appointments with patients where patients give a time range when they are available and so do doctors. How can I do this using javascript? Here’s my inefficient solution.

            // startDate and endDate is the time range for the doctor.
            const startDateTime = startDate.format('HH:mm');
            const endDateTime = endDate.format('HH:mm');

            const stimeParts = startDateTime.split(":");
            const stime1 = parseInt(stimeParts[0], 10);
            const stime2 = parseInt(stimeParts[1], 10);

            const etimeParts = endDateTime.split(":");
            const etime1 = parseInt(etimeParts[0], 10);
            const etime2 = parseInt(etimeParts[1], 10);

            const startminutes = (stime1 * 60) + stime2;
            const endminutes = (etime1 * 60) + etime2;

            // so patients can select times in a 3 hour range
            // for example from 0:00 to 3:00 or 12:00 to 15:00
            // key is the first number in the time range that the user selected
            // so if they select the time range 15:00 to 18:00, then key = 15
            const timeSelected = key;
            const fromMinutesSelected = timeSelected * 60;
            const toMinutesSelected = (timeSelected * 60) + (3 * 60);

            let timeStart = startminutes;

            while ( found === false && (timeStart < endminutes && ((timeStart + 30) <= endminutes))) {
                if (timeStart >= fromMinutesSelected && (timeStart + 30 < toMinutesSelected)) {
                    found = true;
                } else {
                    timeStart += 30;
                }
            }

if found == true then the two time ranges overlap. selectedTime

Math for combining two array’s values as notation for a large number

I am currently trying to write a part of my code that takes a large number, say, 1e31, and converts it to 1no where no is a units measure. I currently have my code set up as such:

function getNotation(num) {
  let firstArray = ["", "un", "du", "tr", "qa", "qi", "sx", "sp", "oc", "no"];
  let secondArray = ["", "Du", "Tr", "Qa", "Qi", "Sx", "Sp", "Oc", "No"];
  let output = "";
  console.log((Math.floor(Math.log10(num) / 3)) + " " + (Math.floor(Math.log10(num) / 3) % 11 - 1) + " " + (Math.floor(Math.floor(Math.log10(num) / 3) / 11)));
  output += firstArray[Math.floor(Math.log10(num) / 3) % 11 - 1];
  output += secondArray[Math.floor(Math.floor(Math.log10(num) / 3) / 11)];
  return output;
}

The issue that I am running into is that the index I use for firstArray works fine until it hits 9, then it jumps to -1. If anyone could give me some help that would be greatly appreciated. Let me know if you need any more of the code.

Pinterest Tag Health Make sure you are including Product IDs in your Add to Cart events. SHOPIFY

Make sure you are including Product IDs in your Add to Cart events. A Product ID can be any format that you choose as long as it matches the format used by your Catalog.

I am getting this error on Pinterest tag health and I don’t know how to fix it. I am using Shopify. I have tried to add this code to submit button:

onclick="pintrk('track', 'addtocart');"

But it is not working. Is this some kind of bug?

How do you click on this deeply nested class in javascript?

How can I access the class I marked blue on the screenshot below and click on it?
The “main class” and “section class” always got the same name. I have tried by starting at a class which I believe is the parent and find about its children step by step by using

var x = document.getElementsByClassName("_9eogI E3X2T")[0];
window.alert(x);

but that keeps giving me “undefined” and I don’t know how to get into the class I marked on the screenshot because the blue marked area in code always got a different name too :/

enter image description here