I am trying to run my checkPrice
function with parameters that I pass in:
const nightmare = require('nightmare')()
let url = "https://www.amazon.co.uk/Guards-Discworld-City-Watch-Collection/dp/1473200180/"
let identifier = "price"
checkPrice(url, identifier)
async function checkPrice(url2, identifier2) {
console.log(identifier2)
const priceString = await nightmare.goto(url2)
.wait(`#${identifier2}`)
.evaluate(() => document.getElementById(identifier2).innerText)
.end()
console.log(priceString)
console.log("Hello!")
}
The problem that I'm getting is that I keep getting "UnhandledPromiseRejectionWarning: ReferenceError: identifier2 is not defined".
If I change the document.getElementById(identifier2).innerText)
to document.getElementById("price").innerText)
then it works fine.
Is there any way to pass through a parameter to getElementById()
in the way I am trying to do?
I have tried putting in a hardcoded value for identifier2
which did work but would mean I am not able to use the function in the way I was planning. I also tried using identifier2
inside of a string (${identifier2}
) which did not work.
Nightmare runs both a Node.js process and a browser process. The main testing code is run in the Node.js process, but Nightmare serializes the function you pass to evaluate
and runs it in the browser process. Since they're in completely different processes, you can't just close over variables. Instead, pass the values you need into evaluate
as subsequent arguments, and update your function signature to expect them as paramters. Here's the example showing this in the documentation:
const selector = 'h1' nightmare .evaluate(selector => { // now we're executing inside the browser scope. return document.querySelector(selector).innerText }, selector) // <-- that's how you pass parameters from Node scope to browser scope .then(text => { // ... })
(That's their code comment. Note that "scope" isn't quite the right word, but it's the general idea.)
Adapting your code to do that:
async function checkPrice(url2, identifier2) {
console.log(identifier2)
const priceString = await nightmare.goto(url2)
.wait(`#${identifier2}`)
.evaluate((identifier2) => document.getElementById(identifier2).innerText, identifier2)
// ^^^^^^^^^^^ ^^^^^^^^^^^^^
.end()
console.log(priceString)
console.log("Hello!")
}