frazap has asked for the wisdom of the Perl Monks concerning the following question:

I have a javascript file that contains a bunch of variables.
var leg = { aa: "a label", ab: "another label", .... }; var map = { aa : ["R1"], ab : ["AA1"], ac : ["AA1", "AA2"], .... }; var monorows = [ ["R6", "c", "1", "CB16", "CB15" ... codes that are listed in map], ... ];
I want to check that these variables are coherent, eg all codes in map are also in monorows, etc. In a first step, I copied the javascript variables in a perl script, changed the syntax to have json data instead of javascript syntax and could run my checks:
use JSON; use Data::Dump "dd"; my $leg_str =<<'END'; { "aa": "label1", "ab": "label2", ... "er": "last label" } END my $leg = decode_json($leg_str);
Now, I would like to automatize the import step. I tried this:
use WWW::Mechanize::PhantomJS; my $js = WWW::Mechanize::PhantomJS->new(); $js->get_local("my_js_file.js"); #print $js->content; I get the content ok here. my ($val, $type) = $js->eval_in_page('function(){JSON.stringify(leg);} +');
But this just return in $val the function is have sent... What am I missing ? is there a way to have this working ?

Thanks

frazap

Replies are listed 'Best First'.
Re: Accessing javascript variable from perl
by Corion (Patriarch) on Jun 14, 2019 at 12:26 UTC

    You need to at least return the value you want in Javascript, and I don't thzink you need the function at all:

    $js->eval_in_page(<<'JS'); return JSON.stringify(leg); JS
      >   return JSON.stringify(leg);

      Does one really need return in an eval?

      Looked into the documentation and it doesn't seem so.

      But of course you know the author of WWW::Mechanize::PhantomJS better than me... ;)

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

      The content calls says:
      <html><head></head><body><pre style="word-wrap: break-word; white-spac +e: pre-wrap;"> //list of the entries in the headings drop box //the keys give the corresponding elements in the rows var leg = { aa: " ... ", ... }; </pre></body></html>
      The return statement gives an error if not included in a 'function () {}'
      Error while executing command: executeScript: An unknown server-side e +rror occurred while processing the command.: {"errorMessage":"Return +statements are only valid inside functions",
      LanX proposal fails also:
      my ($val, $type) = $js->eval_in_page('(function() {return JSON.stringi +fy(leg);})()'); print "val: $val, type: $type\n";
      Gives the error
      Error while executing command: executeScript: An unknown server-side e +rror occurred while processing the command.: {"errorMessage":"Can't f +ind variable: leg","request":{"headers":{"Accept":"application/json", +"Connection":"TE, close","Content-Length":"74","Content-Type":"applic +ation/json; charset=utf-8","Host":"127.0.0.1:8910","TE":"deflate,gzip +;q=0.3","User-Agent":"libwww-perl/6.15"},"httpVersion":"1.1","method" +:"POST","post":"{\"args\":[],\"script\":\"return (function() {return +JSON.stringify(leg);})()\"}","url":"/execute","urlParsed":{"anchor":" +","query":"","file":"execute","directory":"/","path":"/execute","rela +tive":"/execute","port":"","host":"","password":"","user":"","userInf +o":"","authority":"","protocol":"","source":"/execute","queryKey":{}, +"chunks":["execute"]},"urlOriginal":"/session/95efd1d0-8ea9-11e9-b043 +-85beee600173/execute"}} at C:/strawberry/perl/site/lib/Selenium/Remo +te/Driver.pm line 389.

      Update:

      The content seems strange to me, should the js code not be include in script tag ?

        The errorMessages are explicitly given!

        •  "Return statements are only valid inside functions"

          I explained this already

        •  "Can't find variable: leg"

          so my proposal doesnt fail it's your JS Code. Either you can't access the namespace of leg or you misspelled it.

          Though you may want to try window.leg or play around inside your browser's JS console (normally type F12 to get there)

        HINT: var denotes a lexical var inside a function°, it only becomes global* if used outside.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

        updates

        °) mostly like my in Perl except for the hoisting effect

        *) in this case it behaves mostly like our in Perl

Re: Accessing javascript variable from perl
by LanX (Saint) on Jun 14, 2019 at 12:28 UTC
    That's more a JS question

    I think you are only declaring the function without calling it.

      'function(){JSON.stringify(leg);}'

    So better try

      '(function(){return JSON.stringify(leg);})()

    Or just skip the anonymous function

      'JSON.stringify(leg)'

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

    Update:

    And Corion is of course right, you need - contrary to Perl - an explicit return in side JS functions

    Update

    added return to code