Returning in javascript

i made a qr code scanner that works but i cant get it to return the result can someone help

// Helper function to get a cookie by name
function getCookie(name) {
    const value = `; ${document.cookie}`;
    const parts = value.split(`; ${name}=`);
    if (parts.length === 2) return parts.pop().split(';').shift();
}

// Helper function to set a cookie
function setCookie(name, value, days) {
    let expires = "";
    if (days) {
        const date = new Date();
        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
        expires = `; expires=${date.toUTCString()}`;
    }
    document.cookie = `${name}=${value || ""}${expires}; path=/`;
}

// Helper function to delete a cookie
function deleteCookie(name) {
    document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
}

let isRunning = false;

function startWebcam(onQRCodeDetected) {
    if (getCookie('webcamRunning') === 'true') {
        console.log('Webcam is already running. Please wait until it finishes.');
        return;
    }

    setCookie('webcamRunning', 'true', 1); // Set the cookie to indicate the webcam is running

    const modal = document.createElement('div');
    modal.style.position = 'fixed';
    modal.style.top = '50%';
    modal.style.left = '50%';
    modal.style.transform = 'translate(-50%, -50%)';
    modal.style.background = '#f4f4f9';
    modal.style.borderRadius = '8px';
    modal.style.padding = '20px';
    modal.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.2)';
    modal.style.zIndex = 1000;
    modal.style.display = 'none';
    document.body.appendChild(modal);

    const video = document.createElement('video');
    video.style.width = '640px';
    video.style.height = '480px';
    video.style.borderRadius = '8px';
    video.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.2)';
    video.style.transform = 'scaleX(-1)';
    video.autoplay = true;
    video.style.backgroundColor = '#000';
    video.style.position = 'relative';
    modal.appendChild(video);

    const closeButton = document.createElement('button');
    closeButton.textContent = '×';
    closeButton.style.position = 'absolute';
    closeButton.style.top = '10px';
    closeButton.style.right = '10px';
    closeButton.style.background = '#ff5f5f';
    closeButton.style.border = 'none';
    closeButton.style.borderRadius = '50%';
    closeButton.style.fontSize = '24px';
    closeButton.style.color = '#fff';
    closeButton.style.width = '40px';
    closeButton.style.height = '40px';
    closeButton.style.display = 'flex';
    closeButton.style.alignItems = 'center';
    closeButton.style.justifyContent = 'center';
    closeButton.style.cursor = 'pointer';
    closeButton.style.zIndex = 1001;
    closeButton.style.transition = 'background-color 0.3s ease, transform 0.3s ease';
    closeButton.addEventListener('mouseover', () => {
        closeButton.style.backgroundColor = '#ff4c4c';
    });
    closeButton.addEventListener('mouseout', () => {
        closeButton.style.backgroundColor = '#ff5f5f';
    });
    closeButton.onclick = closeWebcam;
    modal.appendChild(closeButton);

    const canvas = document.createElement('canvas');
    canvas.width = 640;
    canvas.height = 480;
    canvas.style.position = 'absolute';
    canvas.style.top = '0';
    canvas.style.left = '0';
    canvas.style.borderRadius = '8px';
    modal.appendChild(canvas);

    const context = canvas.getContext('2d');

    const fileInput = document.createElement('input');
    fileInput.type = 'file';
    fileInput.accept = 'image/*';
    fileInput.style.marginTop = '20px';
    fileInput.style.display = 'block';
    fileInput.onchange = handleFileUpload;
    modal.appendChild(fileInput);

    function drawSquare() {
        const size = 300;
        const x = (canvas.width - size) / 2;
        const y = (canvas.height - size) / 2;
        const radius = 20;

        context.clearRect(0, 0, canvas.width, canvas.height);

        context.strokeStyle = 'white';
        context.lineWidth = 5;
        context.lineJoin = 'round';
        context.lineCap = 'round';

        context.beginPath();
        context.moveTo(x + radius, y);
        context.arcTo(x + size, y, x + size, y + size, radius);
        context.arcTo(x + size, y + size, x, y + size, radius);
        context.arcTo(x, y + size, x, y, radius);
        context.arcTo(x, y, x + size, y, radius);
        context.closePath();
        context.stroke();
    }

    let stream = null;
    let isProcessing = true;

    function closeWebcam() {
        if (stream) {
            stream.getTracks().forEach(track => track.stop());
        }
        document.body.removeChild(modal);
        deleteCookie('webcamRunning'); // Remove the cookie when closing the webcam
        isRunning = false;
    }

    function updateCapturedImage() {
        if (!isProcessing) return;

        const size = 300;
        const x = (canvas.width - size) / 2;
        const y = (canvas.height - size) / 2;

        const tempCanvas = document.createElement('canvas');
        tempCanvas.width = size;
        tempCanvas.height = size;
        const tempContext = tempCanvas.getContext('2d');

        tempContext.drawImage(video, x, y, size, size, 0, 0, size, size);

        const imageData = tempContext.getImageData(0, 0, size, size);
        const data = imageData.data;
        const threshold = 100;
        for (let i = 0; i < data.length; i += 4) {
            const avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
            const binary = avg > threshold ? 255 : 0;
            data[i] = data[i + 1] = data[i + 2] = binary;
        }
        tempContext.putImageData(imageData, 0, 0);

        const formData = new FormData();
        formData.append('file', dataURItoBlob(tempCanvas.toDataURL('image/png')), 'image.png');

        fetch('https://api.qrserver.com/v1/read-qr-code/', {
            method: 'POST',
            body: formData
        })
        .then(response => response.json())
        .then(data => {
            if (data && data[0] && data[0].symbol && data[0].symbol[0] && data[0].symbol[0].data) {
                const result = data[0].symbol[0].data;
                onQRCodeDetected(result);
                isProcessing = false;
                closeWebcam();
            }
        })
        .catch(error => {
            console.error('Error reading QR code:', error);
        });

        requestAnimationFrame(updateCapturedImage);
    }

    function dataURItoBlob(dataURI) {
        const byteString = atob(dataURI.split(',')[1]);
        const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
        const ab = new ArrayBuffer(byteString.length);
        const ia = new Uint8Array(ab);
        for (let i = 0; i < byteString.length; i++) {
            ia[i] = byteString.charCodeAt(i);
        }
        return new Blob([ab], { type: mimeString });
    }

    function handleFileUpload(event) {
        const file = event.target.files[0];
        if (file) {
            const reader = new FileReader();
            reader.onload = function(e) {
                const img = new Image();
                img.onload = function() {
                    const tempCanvas = document.createElement('canvas');
                    tempCanvas.width = img.width;
                    tempCanvas.height = img.height;
                    const tempContext = tempCanvas.getContext('2d');
                    tempContext.drawImage(img, 0, 0);

                    const size = 300;
                    const x = (tempCanvas.width - size) / 2;
                    const y = (tempCanvas.height - size) / 2;

                    const imageData = tempContext.getImageData(x, y, size, size);
                    const data = imageData.data;
                    const threshold = 100;
                    for (let i = 0; i < data.length; i += 4) {
                        const avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
                        const binary = avg > threshold ? 255 : 0;
                        data[i] = data[i + 1] = data[i + 2] = binary;
                    }
                    tempContext.putImageData(imageData, 0, 0);

                    const formData = new FormData();
                    formData.append('file', dataURItoBlob(tempCanvas.toDataURL('image/png')), 'image.png');

                    fetch('https://api.qrserver.com/v1/read-qr-code/', {
                        method: 'POST',
                        body: formData
                    })
                    .then(response => response.json())
                    .then(data => {
                        if (data && data[0] && data[0].symbol && data[0].symbol[0] && data[0].symbol[0].data) {
                            const result = data[0].symbol[0].data;
                            onQRCodeDetected(result);
                            isProcessing = false;
                            closeWebcam();
                        }
                    })
                    .catch(error => {
                        console.error('Error reading QR code:', error);
                    });
                };
                img.src = e.target.result;
            };
            reader.readAsDataURL(file);
        }
    }

    navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } })
        .then(mediaStream => {
            stream = mediaStream;
            video.srcObject = mediaStream;
            video.play();
            modal.style.display = 'block';

            function updateCanvas() {
                drawSquare();
                requestAnimationFrame(updateCanvas);
            }
            updateCanvas();

            updateCapturedImage();
        })
        .catch(err => {
            console.error('Error accessing webcam: ', err);
            deleteCookie('webcamRunning'); // Remove the cookie if there's an error
        });
}
var done = false
// Start the webcam
startWebcam(result => {
    console.log('QR Code Detected:', result);
   // alert('QR Code Detected: ' + result);
      done = true
return new List([true, result])
});

@ego-lay_atman-bay

Just like in the other post, this isn't quite the SO (StackOverflow) you're expecting to get outta this post. You're probably better off posting this in a text-based coding QnA forum. I don't think @ego-lay_atman-bay's gonna help.

bud. im asking for snap help

Where's the Snap! then? Not trying to be rude.

go to my post abt js

I'm pretty sure they're just asking how to report some kind of data from a javascript promise (not exactly what they're doing, but it's pretty much the same idea) in snap.

And to @avi_shor, I do know how to do it, however I'm currently on my phone, so I'll tell you tomorrow.

thank god. i tried everything i could. i have an idea using cookies like i did to prevent the but idk

If it's a Promise, I do...

var myPromise = new Promise(/* ... */)
var ready = {canRead: false}
(async function() {
ready.res = await myPromise
ready.canRead = true
})()
return ready

I know that JS objects change as long as it's the same object you modify and get from. So, in Snap you can do a...

set [ready V] to (call (JavaScript function \( @verticalEllipsis @addInput \) \{[`your code...`]}) @verticalEllipsis @addInput)
wait until (call (JavaScript function \([rd] @delInput @verticalEllipsis @addInput \) \{[`return rd.canRead`]}) with inputs (ready) @delInput @verticalEllipsis @addInput)
set [result V] to (call (JavaScript function \([rd] @delInput @verticalEllipsis @addInput \) \{[`return rd.res`]}) with inputs (ready) @delInput @verticalEllipsis @addInput)

/* do whatever you want with result */

There's no reason to use cookies.

The main idea is to return a function that returns a list of whether it's done, and the result, and then you just use snap to wait until the first value in the list (after calling the function to get the list), and then return the second item.

i tried that it wasnt working and i didnt know why

also if you really look into the code i implemented a way to track the qr code if wanted in the future

Here's how to do it.

And here's a working demo that has the same idea.

You don't need to use cookies at all, in fact if you're going to store global variables, just put them on the window object, it's much better.

where does my code go

did you test to make sure this works because it still isnt working for me

fixed. thx

can this be made without js

A qr code scanner? Technically it's possible, but it's probably really hard.

i wanna use the url block to do it but idk if i can send a costume through it

I don't think it's possible to get a base64 encoding of a costume without js, and I don't think you would want to create a whole png encoder in snap.