Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

evaluate returns null when expected result is a list #243

Open
rohitsangwan01 opened this issue Jun 28, 2023 · 10 comments
Open

evaluate returns null when expected result is a list #243

rohitsangwan01 opened this issue Jun 28, 2023 · 10 comments

Comments

@rohitsangwan01
Copy link

rohitsangwan01 commented Jun 28, 2023

Hey thanks for this awesome library

am facing an issue
when i try to evaluate a method which should return a list, then evaluate method returns null
but if i use evaluateHandle, then it returns list of JsHandle which seems to be fine

and i am sure that , js method is fine and returns proper value, because i tried executing that manually and its fine
and am facing this issue only when expecting result is a List, rest all cases works fine

with this , i also face an issue if i try to execute a method with parameter as list, for example

evaluate('''SomeMethod( [ "someData" ] )''') this will not work

but this works : evaluate('''SomeMethod( [ ] )'''), or we pass something else , that will also works
and i have to pass args like this , can't use args parameter from Puppeteer in my case

@xvrh
Copy link
Owner

xvrh commented Jun 28, 2023

Can you provide a way to reproduce?

Just tried something like that and it seems to work as expected:

import 'package:puppeteer/puppeteer.dart';

void main() async {
  var browser = await puppeteer.launch();
  var page = await browser.newPage();

  var result = await page.evaluate('() => ["someData"]');
  print('$result ${(result as List).first} ${result.runtimeType}');
  // => [someData] someData List<dynamic>

  var result2 = await page.evaluate('(a) => a', args: [
    ['myarg']
  ]);
  print('$result2 ${(result2 as List).first} ${result2.runtimeType}');
  // => [myarg] myarg List<dynamic>

  await browser.close();
}

@rohitsangwan01
Copy link
Author

rohitsangwan01 commented Jun 28, 2023

@xvrh here in my library am using puppeteer for desktop
and when i call this method or other similar methods which should return a list, but returning null

but on mobile platform it returns correct list

for desktop am using this to get result, and if i use evaluateHandler instead of this , then am getting a list (but in JsHandler form )

on mobile am using this

Edit : and are you able to evaluate a method with args as list, for example in my case
page?.evaluate('''Wpp.someMethod("arg1",["arg2","arg3"]);''')
so here if i pass list as argument within the method string, then puppeteer throws some error
i can't use this page.evaluate('(a) => a', args: [['myarg']]);
because i have to build a string common for both mobile and desktop platform

@xvrh
Copy link
Owner

xvrh commented Jun 28, 2023

In your evaluateJs implementation in wp_client_desktop, can you wrap the source inside a function?

var result = await page?.evaluate('() => $source');

@rohitsangwan01
Copy link
Author

In your evaluateJs implementation in wp_client_desktop, can you wrap the source inside a function?

var result = await page?.evaluate('() => $source');

yes trying

@rohitsangwan01
Copy link
Author

rohitsangwan01 commented Jun 28, 2023

@xvrh adding '() => $source' have same result , fixed that list issue ( passing list as args )

but still getting issue in getting result when expecting list
Here is result of

evaluate : null
evaluateHandle -> properties : {0: JSHandle@object, 1: JSHandle@object, 2: JSHandle@object, 3: JSHandle@object}

@rohitsangwan01
Copy link
Author

rohitsangwan01 commented Jun 28, 2023

@xvrh tried to replicating something like this

  String content = '''
        window.getData = () => {
          return new Promise((resolve, reject) => {
            setTimeout(() => {
              resolve([{ "someData" : 3 },{ "randomData" : 2}])
            }, 1000);
          });
        };
    ''';

  await page.addScriptTag(content: content, type: "module");
  var result = await page.evaluate('window.getData()');

and its also working fine, but strangely its not working as expected in my library when i use WPP.group.getAllGroups();
but if i execute this on mobile ( in webView ), then returning result
do you think this can be because of large data or large list or something unable to parse in json ?

@rohitsangwan01
Copy link
Author

rohitsangwan01 commented Jun 28, 2023

@xvrh one thing i noticed with these methods which are returning null is :
evaluateHandle returns jsHandler but jsHandler.jsonValue throws error : Object reference chain is too long
and jsHandler.jsonValue works fine for other methods ( which are already working fine with evaluate )

@xvrh
Copy link
Owner

xvrh commented Jun 28, 2023

do you think this can be because of large data or large list or something unable to parse in json

Can you try to debug by taking only some small part of the array. ie:

  var result = await page.evaluate('async () => (await WPP.group.getAllGroups()).slice(0, 10)');

@rohitsangwan01
Copy link
Author

still getting null after trying async () => (await WPP.group.getAllGroups()).slice(0, 10)'

i also tried : async () => (await WPP.group.getAllGroups())[0] and got null

but when i tried evaluateHandle with above , i got the result as expected ( in jsHandle )
jsHandle.properties returns :
{revisionNumber: JSHandle:32, __x_stale: JSHandle@object, __fired: JSHandle:null, ........

@rohitsangwan01
Copy link
Author

@xvrh finally got the solution

This worked for me :
var result = await page?.evaluate('async () => JSON.stringify(await WPP.group.getAllGroups())');

seems like issue is with the parsing on dart side, if we parse the result within js , then its working fine

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants