0

The answers to the supposed duplicate question do address how to pass a parameter to the function but if you had actually read the question you would see that it was originally about the script hanging.

I am new to PhantomJS and just know enough javascript to make a mess.

Here is my script ...

"use strict";
var page = require('webpage').create();

page.onConsoleMessage = function(msg) { console.log(msg); };

page.open("https://developer.amazon.com/home.html", function(status) {
        if (status === "success") {
                console.log("SUCCESS");
                var title = page.evaluate(function() { return document.title;});
                console.log( title );
                var forms = page.evaluate(function() { return document.forms;});
                console.log( forms.length );
                var num_elements = page.evaluate(function() {return document.forms[0].elements.length;});
                console.log( num_elements );
//              for each ( var e in document.forms[0].elements ) {
//                      console.log( "e.name = [" + e.name + " e.value = [" + e.value + "]" );
//              }
                for ( var i=0; i < document.forms[0].elements.length; i++ ) {
                        console.log( "name = [" + document.forms[0].elements[i].name + "]" );
                }
        } else {
                phantom.exit(1);
        }
        phantom.exit(0);
});

When I run it I get this output and then the script seems to hang:

SUCCESS
Amazon.com Sign In
1
18

I don't think I have any typos and don't understand why my loop is not working.

Thanks

Update:

Thanks to Deryck's help I have modified my script to this:

"use strict";
var page = require('webpage').create();

page.onConsoleMessage = function(msg) { console.log(msg); };

page.open("https://developer.amazon.com/home.html", function(status) {
        if (status === "success") {
                console.log("SUCCESS");
                var title = page.evaluate(function() { return document.title;});
                console.log( title );
                var forms = page.evaluate(function() { return document.forms;});
                console.log( forms.length );
                var num_elements = page.evaluate(function() {return document.forms[0].elements.length;});
                console.log( num_elements );
//              for each ( var e in document.forms[0].elements ) {
//                      console.log( "e.name = [" + e.name + " e.value = [" + e.value + "]" );
//              }
                for ( var i=0; i < num_elements; i++ ) {
                        console.log( i );
                        console.log( "name = [" +
                                page.evaluate(
                                        function() {
                                                return document.forms[0].elements[i].name
                                        }
                                )
                        + "]" );
                }
        } else {
                phantom.exit(1);
        }
        phantom.exit(0);
});

But I am getting this error ...

SUCCESS
Amazon.com Sign In
1
18
0
ReferenceError: Can't find variable: i

  undefined:2
  :3
name = [null]
Red Cricket
  • 9,762
  • 21
  • 81
  • 166
  • Well I've actually never used PhantomJS but it seems everywhere you have `document.[...]` work successfully, you have to wrap it in a `page.evaluate(function () {...})` and your *for-loop* is not wrapped in that. – Deryck Jun 16 '16 at 02:11
  • Ah! I see. Thanks. How do I pass the value of "i" to the function? – Red Cricket Jun 16 '16 at 02:16
  • well, `i` will be available based on the scope already so you don't need to worry about that – Deryck Jun 16 '16 at 02:20
  • I guess the i in not available. I have updated my question. Maybe I messed something else up :) – Red Cricket Jun 16 '16 at 02:35
  • That would probably mean that `page.evaluate` is turning that function into a string then re-evaluating. Makes sense. So instead just put the entire for-loop inside the function and have it return an array, then you can `console.log(returnedArray)` – Deryck Jun 16 '16 at 02:47

1 Answers1

1

The function you pass to page.evaluate will not have access to the variables present in the phantom script; that's because the function code is passed to the page, then evaluated.

Use this form of page.evaluate to pass i:

console.log( "name = [" +
  page.evaluate(function(i) {
    return document.forms[0].elements[i].name;
  }, i)
+ "]");
Jacob
  • 77,566
  • 24
  • 149
  • 228