evaluate()

evaluate(inPageFunction [, argumentObject, callback])

Executes inPageFunction in the current page context.

Nick provides you with two separate JavaScript contexts:

  1. Where the Nick code runs: this is your script environment, with all your locally declared variables and all your calls to Nick methods
  2. Where the page code runs: this is where the page executes jQuery or AngularJS code for example

The evaluate() method allows you to declare a function in your Nick context (1) and executes it in the page context (2). It's like executing code in your browser's inspector tool: you can do anything you want with the page.

In the page context, you have access to all the global variables declared by the page, as well as the DOM (window, document, ...). Any JavaScript libraries included by the page can also be used.

If the page does not include what you want (jQuery or underscore for example), you can inject any JavaScript file with inject() before calling evaluate().

— inPageFunction (Function(argumentObject, callback))

Function to execute in the current page context. argumentObject will be passed as its first argument and a callback as it second argument.
argumentObject is an empty plainObject by default.
callback is the function to call when finished.

  • err (String): null if the function succeeds otherwise put a description of what went wrong
  • res (Any): return value of inPageFunction in case of success (this value is serialized to be transferred back to the Nick context — complex object like DOM elements, functions or jQuery objects cannot be returned to the Nick context reliably)

— [argumentObject] (PlainObject)

Optional object that will be passed as an argument of inPageFunction (optional).
This object is serialized to be transferred to the page context — complex objects like functions or JavaScript modules cannot be passed as argument reliably.

— callback (Function(err, res)

Function called when finished.

  • err (String): null or a string describing what went wrong during the evaluation of inPageFunction
  • res (Any): return value of inPageFunction in case of success (this value is serialized to be transferred back to the Nick context — complex object like DOM elements, functions or jQuery objects cannot be returned to the Nick context reliably)
const scraper = (arg, done) => {
  // In this case, the current page uses a typical jQuery declared as $
  done(null, $(arg.link).attr("href"))
}
const arg = { link: "#header > a.title" }

try {
  const res = await tab.evaluate(scraper, arg)
  console.log("Scraped this link:", res)
  // Continue your navigation here
} catch (err) {
  console.log("Something went wrong:", err)
}
const scraper = (arg, done) => {
  // In this case, the current page uses a typical jQuery declared as $
  done(null, $(arg.link).attr("href"))
}
const arg = { link: "#header > a.title" }

tab.evaluate(scraper, arg)
.then((res) => {
  console.log("Scraped this link:", res)
  // Continue your navigation here
})
.catch((err) => {
  console.log("Something went wrong:", err)
})
var scraper = function(arg, done) {
  // In this case, the current page uses a typical jQuery declared as $
  done(null, $(arg.link).attr("href"))
}
var arg = { link: "#header > a.title" }

tab.evaluate(scraper, arg, function(err, res) {
  if (err) {
    console.log("Something went wrong:", err)
  } else {
    console.log("Scraped this link:", res)
    // Continue your navigation here
  }
})

❗️

Local variables not accessible

Because inPageFunction is executed in the current page context, your local variables that have been declared before your evaluate() call will not be accessible. You can, however, transfer variables using the argumentObject parameter.

For this reason, Nick methods won't be available inside evaluate.

❗️

Error in callback

When returning data with the callback in the inPageFunction take care to always set the first argument as null if there is no error.

🚧

Serialization subtleties

Keep in mind that to transfer inPageFunction and its return value to and from the page context, serialization has to occur. Everything becomes a string at some point. So you cannot return DOM elements or jQuery objects from the page. Moreover, the underlying PhantomJS browser has a bug where serialization of null gives an empty string "" (even in nested objects and arrays). Beware!