Help with js code to screenshot webcam

Hi everyone, I’d like to know why I can’t get the result of the javascript action it’s always either “null” or “undefined” I’ve tested 50 possible codes it never works…

In the code I use the element qr code reader and I try to screenshot an image of the preview and to have a link of this image in a variable

image
image


image

THE CODE :

// Accéder aux variables globales
const qrImageURLVarName = ‘a9ef5f76-3892-4011-971e-1ea846708055’;
const qrCodeReaderCameraID = variables[‘33ffb9fe-b797-487a-a038-cd0cf7f00901-cameras’]?.[0];

// Fonction pour traiter l’image et retourner une promesse
function processImage() {
return new Promise((resolve, reject) => {
const qrCodeReaderElement = wwLib.getFrontDocument().getElementById(qrCodeReaderCameraID);

    if (qrCodeReaderElement) {
        qrCodeReaderElement.addEventListener('loadeddata', function() {
            const canvas = document.createElement('canvas');
            canvas.width = qrCodeReaderElement.videoWidth;
            canvas.height = qrCodeReaderElement.videoHeight;

            const ctx = canvas.getContext('2d');
            ctx.drawImage(qrCodeReaderElement, 0, 0, canvas.width, canvas.height);

            const imageData = canvas.toDataURL('image/jpeg');

            // Ici, utilisez la méthode appropriée pour définir la variable globale dans WeWeb
            // Remplacez la ligne suivante par la méthode correcte selon la documentation WeWeb
            // Exemple : setGlobalVariable(qrImageURLVarName, imageData);

            resolve(imageData);
        });
    } else {
        console.error('Élément QR Code Reader non trouvé avec l\'ID:', qrCodeReaderCameraID);
        reject('Élément QR Code Reader non trouvé');
    }
});

}

// Appeler la fonction et traiter la valeur de retour
processImage().then(imageData => {
// imageData est disponible ici
console.log(‘URL de l'image capturée:’, imageData);

// Vous pouvez utiliser imageData ici
// Par exemple :
// displayImage(imageData);

}).catch(error => {
// Gérer les erreurs ici
console.error(‘Erreur lors du traitement de l'image:’, error);
});

// Toute tentative d’accéder à imageData en dehors de la fonction then() donnera undefined

In the then part you have no return. You code need to return something so it end up inside the action result variable.

I guess add
return imageData
instead of
console.log(‘URL de l'image capturée:’, imageData);

here is the code and it still dont work :frowning:

// Accéder aux variables globales
const qrImageURLVarName = variables['a9ef5f76-3892-4011-971e-1ea846708055'];
const qrCodeReaderCameraID = variables['78180aed-7ffb-4da1-8187-61d4f3c64968-cameras']?.[0];

// Fonction pour traiter l’image et retourner une promesse
function processImage() {
    return new Promise((resolve, reject) => {
        const qrCodeReaderElement = wwLib.getFrontDocument().getElementById(qrCodeReaderCameraID);

        if (qrCodeReaderElement) {
            qrCodeReaderElement.addEventListener('loadeddata', function() {
                const canvas = document.createElement('canvas');
                canvas.width = qrCodeReaderElement.videoWidth;
                canvas.height = qrCodeReaderElement.videoHeight;

                const ctx = canvas.getContext('2d');
                ctx.drawImage(qrCodeReaderElement, 0, 0, canvas.width, canvas.height);

                const imageData = canvas.toDataURL('image/jpeg');

                // Ici, utilisez la méthode appropriée pour définir la variable globale dans WeWeb
                // Remplacez la ligne suivante par la méthode correcte selon la documentation WeWeb
                // Exemple : setGlobalVariable(qrImageURLVarName, imageData);

                resolve(imageData);
            });
        } else {
            console.error('Élément QR Code Reader non trouvé avec l\'ID:', qrCodeReaderCameraID);
            reject('Élément QR Code Reader non trouvé');
        }
    });
}

// Appeler la fonction et traiter la valeur de retour
processImage().then(imageData => {
    // Retourner imageData pour qu'il soit disponible dans la variable de résultat de l'action
    return imageData;
}).catch(error => {
    // Gérer les erreurs ici
    console.error('Erreur lors du traitement de l\'image:', error);
});

// Toute tentative d’accéder à imageData en dehors de la fonction then() donnera undefined

The explorer will probably always display it as null but did you try to use the result to confirm its null when you execute the workflow ?

yes

Do you have a slack or discord so we can discuss ? thank you !

Two thoughts:

  1. For your invocation, try
return processImage();

Instead of the processImage.then() syntax. That will more clearly send the promise and its result back to the workflow. The workflow is already in an asynchronous context so that should work well.

  1. If that doesn’t get you there, I’d use console.log(imageData) inside your processImage function to see what it actually generates and that we are good with that that looks like. You can retrieve the result of the console.log in devtools.

We work on this kind of lowcode problem all the time as part of our focus on the hardest 5% in our daily State Change office hours.

1 Like

For now we have only this forum, we want to handle as much discussion as we can here si it can benefit to other users in the community.

I let you follow the @raydeck suggestions and we can continue to help you here :slight_smile:

i tried many js codes and still not working, i always get the result null or undefined. I think its not the code the problem, its something else

If you erase everything and only put something like return 'hello', do you get something on the result ?

Raydeck suggested you to add a console.log(imageData) under this part

const imageData = canvas.toDataURL('image/jpeg');

So we can try to figure out at which point the code doesn’t perform as expected

Please, if you share code, wrap it between three `, it will generate a code block, I added it for you

Yes for “hello” it worked

Corriged the code but still ‘undefined’

const qrImageURLVarName = variables[/* qrImageURL */'a9ef5f76-3892-4011-971e-1ea846708055'];
const qrCodeReaderCameraID = variables[/* QR Code Reader */'78180aed-7ffb-4da1-8187-61d4f3c64968-cameras'];

// Fonction pour traiter l’image et retourner une promesse
function processImage() {
    return new Promise((resolve, reject) => {
        const qrCodeReaderElement = wwLib.getFrontDocument().getElementById(qrCodeReaderCameraID);

        if (qrCodeReaderElement) {
            qrCodeReaderElement.addEventListener('loadeddata', function() {
                const canvas = document.createElement('canvas');
                canvas.width = qrCodeReaderElement.videoWidth;
                canvas.height = qrCodeReaderElement.videoHeight;

                const ctx = canvas.getContext('2d');
                ctx.drawImage(qrCodeReaderElement, 0, 0, canvas.width, canvas.height);

                const imageData = canvas.toDataURL('image/jpeg');

                // Ajout d'un console.log pour le débogage
                console.log(imageData);

                // Remplacez cette ligne par la méthode correcte selon la documentation WeWeb
                // setGlobalVariable(qrImageURLVarName, imageData);

                resolve(imageData);
            });
        } else {
            console.error('Élément QR Code Reader non trouvé avec l\'ID:', qrCodeReaderCameraID);
            reject('Élément QR Code Reader non trouvé');
        }
    });
}

// Appeler la fonction et traiter la valeur de retour
processImage().then(imageData => {
    // Retourner imageData pour qu'il soit disponible dans la variable de résultat de l'action
    return imageData;
}).catch(error => {
    // Gérer les erreurs ici
    console.error('Erreur lors du traitement de l\'image:', error);
});

// Toute tentative d’accéder à imageData en dehors de la fonction then() donnera undefined```

![image|350x358](upload://zXMSSW8mB08JPkrRlE0qxraybp0.png)

How can I get details of errors if they don't appear in the logs? 

![image|418x246](upload://v2qsZ2osekuoTh4fA33qFi6Zvgo.png)

Your function has to throw error instead of catching it if you want it to show up inside the Editor logs.

Could you try to replace

processImage().then(imageData => {
    // Retourner imageData pour qu'il soit disponible dans la variable de résultat de l'action
    return imageData;
}).catch(error => {
    // Gérer les erreurs ici
    console.error('Erreur lors du traitement de l\'image:', error);
});

with

return await processImage()

Also do you have any logs in the browser console ?

1 Like

I have this error now

This part doesn’t seem to work as expected, did you put the correct id you’re searching for on the element ?

Yes i put the correct id…

If you have the time, of course, Alexis, you could reproduce the workflow quickly on your side? to see if it works with me or not. Thank you, Alexis!

I dont think it’s the ID of the element. It’s the ID of the camera. Its not the same thing.

Your code is trying to retrieve the HTML element associated with a given ID. The ID of the element si what you type inside the id input on the settings of your element.

Btw, it seems you want to target the video element as you’re listening to loaded data, so you should probably replace your getElementById with

const qrCodeReaderElement = wwLib.getFrontDocument().querySelector('#reader > video')

Where “reader” is the id you can put on the html attribute of your qrcode element, from the settings.

I’m just helping you with your code, I don’t know if it will do what you expect. Be aware there is already a canvas element so maybe you want to target it directly too instead of creating another one. To select it you can do something similar:

const qrCodeReaderElement = wwLib.getFrontDocument().querySelector('#reader > canvas')

Thank you, it finally works!! I am putting the code below for those who are interested (replace ‘camerarayane’ with the id of your element to screenshot). However, do you know how to convert the base64 URL into a .png URL or another format?

const qrImageURLVarName = 'a9ef5f76-3892-4011-971e-1ea846708055'; // Replace with the actual variable name as needed

// Function to process the image and return a promise
function processImage() {
  return new Promise((resolve, reject) => {
    // Updated querySelector to target the canvas within the element with the ID 'camerarayane'
    const qrCodeReaderElement = wwLib.getFrontDocument().querySelector('#camerarayane > canvas');

    if (qrCodeReaderElement) {
      // Assuming the canvas already has the video drawn onto it
      const imageData = qrCodeReaderElement.toDataURL('image/jpeg');
      // Use the appropriate method to set the global variable in WeWeb
      // Replace the following line with the correct method according to WeWeb documentation
      // Example: setGlobalVariable(qrImageURLVarName, imageData);

      resolve(imageData);
    } else {
      console.error('QR Code Reader canvas element not found within the #camerarayane element');
      reject('QR Code Reader canvas element not found');
    }
  });
}

// Invoke the function and handle the return value
return processImage().then(imageData => {
  // Return imageData to be available in the action result variable
  return imageData;
}).catch(error => {
  // Handle errors here
  console.error('Error processing the image:', error);
});
1 Like

I think you can improve your code by replacing everything with this shorter version

const qrCodeReaderElement = wwLib.getFrontDocument().querySelector('#camerarayane > canvas');
return qrCodeReaderElement?.toDataURL('image/jpeg');

I’m not sure to understand what you mean by converting into a .png URL. What you get is already an url you can use and paste inside the image element to display it for example.

1 Like

In fact I was receiving a base 64 image but I’ve corrected the problem thank you