1

I'm using PhantomJS to snap a screenshot of the dashboard and save it as a PNG file. This works great, but when I add some additional arguments (line, dFrom, dTo) and want to use them inside the page.evaluateJavaScript(), it doesn't work. Is there a way to use PhantomJS variables inside the JavaScript function?

var page = require('webpage').create(),
system = require('system'),
address, output, size, line, dFrom, dTo;

address = system.args[1];
output = system.args[2];
line = "All";
dFrom = null; 
dTo = null;

if (system.args.length > 2)
{
   line = system.args[3];
   dFrom = system.args[4];
   dTo = system.args[5];        
}

page.viewportSize = { width: 1200, height: 1800 };

page.open(address, function (status) {
    if (status !== 'success') {
        console.log('Unable to load the address!');
        phantom.exit();
    } else {
         page.evaluate(function () { 
             var body = document.body; 
             body.style.backgroundColor = '#fff'; 
             body.querySelector('div#nav-section').style.display = 'none'; 
             body.querySelector('div#to-hide-btns').style.display = 'none';
             body.querySelector('div#main-section').style.overflow = 'hidden'; 
        });
        page.evaluateJavaScript(function () {
            selectedLine = line;
            dateFrom = dFrom;
            dateTo = dTo; 
            onCriteriaChange();
        });
        window.setTimeout(function () {
            page.render(output, {format: 'png', quality: '100'});
            console.log('done');
            phantom.exit();
        }, 2000);
    }
})

If I change it to this it works:

page.evaluateJavaScript(function () {
    selectedLine = "S01";
    dateFrom = "3/1/2015";
    dateTo = "3/10/2015"; 
    onCriteriaChange();
});

1 Answer 1

3

page.evaluate() and its siblings are the door to the sandboxed page context. The function that you pass into it has no access to variables defined on the outside. You will need explicitly pass those values into the page context:

page.evaluate(function(line, dFrom, dTo) {
    selectedLine = line;
    dateFrom = dFrom;
    dateTo = dTo; 
    onCriteriaChange();
}, line, dFrom, dTo);

You also cannot pass arbitrary objects around. They need to be serializable:

Note: The arguments and the return value to the evaluate function must be a simple primitive object. The rule of thumb: if it can be serialized via JSON, then it is fine.

Closures, functions, DOM nodes, etc. will not work!

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.