I'm running a Nightmare.js script, and within it I'm trying to require
lodash
(installed locally with npm, in node_modules, registered in package.json).
index.js :
var Nightmare = require('nightmare');
var _ = require('lodash');
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
function getElms(elm) {
var elsm = document.querySelectorAll(elm);
return _.map(elsm, function(elem){ return elem.innerHTML; });
}
var someWebsite = new Nightmare({ show: false })
.goto( ***some url*** )
.wait(getRandomInt(2500, 5000))
.evaluate(function () {
var elsm = document.querySelectorAll(***some selector***);
return _.map(elsm, function(elem){ return elem.innerHTML; });
// return getElms(***some selector***);
}).then(function(linkstexts) {
console.log(linkstexts)
});
but I'm getting this:
UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): _ is not defined
- similar issue if I uncomment and use
return getElms(***some selector***);
- similar issue if I uncomment and use
This is package.json
{
"name": "nightxp",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"lodash": "^4.17.4",
"nightmare": "^2.10.0"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
What am I missing?
UPDATE
I tried passing the lodash to the browser scope, and completing with catch()
,
but somehow the lodash variable still isnt being passed to the scope (example with hackernews):
var Nightmare = require('nightmare');
var lodash = require('lodash');
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
var facebook = new Nightmare({ show: false })
.goto('https://news.ycombinator.com')
.wait(getRandomInt(5500, 6000))
.evaluate( (lodash) => {
var elsm = document.querySelectorAll('tr td.title a.storylink');
return lodash.map(elsm, function(elem){ return elem.innerHTML; });
}, lodash).then(function(titles) {
console.log(titles)
}).catch(function (error) {
console.error('Error:', error);
});
and this is what I get:
C:\Projects\nightmare>set DEBUG=nightmare & node index.js
nightmare queuing process start +0ms
nightmare queueing action "goto" for https://news.ycombinator.com +4ms
nightmare queueing action "wait" +2ms
nightmare queueing action "evaluate" +0ms
nightmare running +1ms
Error: Cannot read property 'map' of undefined
When you run
You are now in browser scope — you can think of
Nightmare.evaluate
as running the contained code in the context of an independent browser, which means your global scope, including_
is not available.See here for a bit more info and some tips on passing data into the scope:
https://github.com/segmentio/nightmare/issues/89
https://github.com/segmentio/nightmare/issues/333
Edit:
While you can pass simple values into evaluate from the node context, you can't pass complex values with functions and methods. This is because the arguments are serialize in transit and this is difficult with functions. Here's an issue that explains it a bit:
https://github.com/segmentio/nightmare/issues/349
In this particular case it seems like the easiest thing to do is to work without lodash, which these days isn't hard. For example: