1

I have a Node.js application which is connected to MongoDb. I am retrieving a certain json from my mongodb collection using findOne() so the value is obtained in a callback. My application also has browser automation tasks using puppeteer. To fill in a certain input field I am trying to use the json that I retrieved from mongodb collection. But due to the asynchronous nature I am unable to use the callback value outside the function. I need to use the callback value to send as an input for the puppeteer.

I have tried to fetch the value from findOne() callback using another function but still unable to use it for the puppeteer async function.

The below code fetches the value from mongodb:

var g;


db.collection("users").findOne({}, function(err, result) {
    if (err) throw err;
    storedata(result);  

});

function  storedata (x){
    g = x;
    //console.log(g);
}

Puppeteer code:

(async () => {
    const browser = await puppeteer.launch({
        headless: false
    })
    const page = await browser.newPage();          

    await page.goto('http://0.0.0.0:4200/')

    await page.$eval('[placeholder="BPMN xml"]', el => {
        return el.value = g
    })
})()

I always get the error g is not defined. Of course, I understand that scope of g is within the function but even when I tried to place the puppeteer code inside the function storedata() I get g undefined error. Kindly help me in understanding the callback values in a better way.

6
  • 1
    But where is g defined? It's nowhere in your code. Commented Aug 5, 2019 at 17:11
  • Is the pupeteer code in the same file as your mongoDB code? Commented Aug 5, 2019 at 17:34
  • @ThomasDondorf I have defined in the top section but havent shown here. I then assigned the value of g = x thinking that it will simply override the value. Commented Aug 5, 2019 at 17:56
  • @dar Yes. It is both in the same file app.js Commented Aug 5, 2019 at 17:56
  • Try explicitly passing 'g' into your anonymous Puppeteer code and then again into your 'page.$eval()' call back. Does it recognize 'g' then? Commented Aug 5, 2019 at 18:10

1 Answer 1

2

The problem is that you pass g to the browser environment. The variable only exists inside your Node.js environment, but you explicitly have to pass it to the browser environment so that you can use it.

Quote from the docs (third argument for page.$eval):

...args <...Serializable|JSHandle> Arguments to pass to pageFunction

Code Sample:

await page.$eval('[placeholder="BPMN xml"]', (el, g) => {
    return el.value = g
}, g);

You pass g as a third argument, which will then become your second argument in your function inside the page.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.