D Cooper D Cooper - 20 days ago 15
Node.js Question

How can multiple queries be made when using NightmareJS?

The below Javascript is intended to use NightmareJS to search a website for 3 posts and return the username of whoever uploaded the post.

var Nightmare = require('nightmare');
var nightmare = Nightmare({ show: true });

var inputArray = [198,199,201];


var runNext = function (i) {

nightmare
.goto('http://theshitpit.com/goto.php')
.insert('form [name=postnum]', i)
.click('form [type=submit]')
.wait()
.evaluate(function () {
return document.querySelector('.username').innerHTML
})
.end()
.then(function (result) {
console.log(result)
})
.catch(function (error) {
console.error('Search failed:', error);
});

}


var index = 0;

while(index<inputArray.length){
runNext(inputArray[index]);
index++;
}


For some reason, this code outputs the following when executed in the Command Prompt:

Search failed {}
Search failed {}


I've been struggling to understand why this is not working. I have tried using this code (without the while loop) to run only once for a specific post, using
runNext(inputArray[0])
and this works fine. So, when I try adding a while loop to get info about multiple posts, why is it not working?

Answer

Nightmare is asynchronous. The errors happen because you are calling runNext three times in a loop at once - not waiting for the previous searches to finish.

So the first two searches are intterupted right after the start and only the last has time to complete.

Try to launch next search at the end of the previous one:

var Nightmare = require('nightmare');
var nightmare = Nightmare({ show: true });

var inputArray = [198, 199, 201];

var index = 0;
var runNext = function (i) {

  nightmare
    .goto('http://theshitpit.com/goto.php')
    .insert('form [name=postnum]', inputArray[i])
    .click('form [type=submit]')
    .wait()
    .evaluate(function () {
        return document.querySelector('.username').innerHTML
    })
    .then(function (result) {
        console.log(result);
    })
    .then(function(){
        index++;

        // We will only run bext search when we successfully got here
        if(index < inputArray.length){
            runNext(index);
        } else {
            console.log("End");
            nightmare.halt();
        }
    })
    .catch(function (error) {
        console.error('Search failed:', error);
    });

}

runNext(index);