0

I am not much skilled with JS. I want to pass the "i" variable (page's number) in the hash. I tried this but it says

Error: Evaluation failed: ReferenceError: i is not defined

async function searchResults(domain, keyword) {

  let [page, browser] = await initPuppeteer(domain)
  let products = []

  for (let i = 1; i <= 2; i++) {

    let url = `https://www.example.com/test?page=${i}`
    await page.goto(url)
    let products_page = await page.$$eval(
        '[data]',
        divs => divs.map( div => ({
            page: i <--- Need to access the outer loop iterator here
          })
        )
    );

    asins.push(products_page)
  }

  await browser.close();
  return products.flat()
}
shim
  • 9,289
  • 12
  • 69
  • 108
sparkle
  • 7,530
  • 22
  • 69
  • 131
  • 1
    Do you really mean the *hash*? If so, replace `?` with `#`. `?` starts the *query string*. `#` starts the *hash fragment*. E.g., ```let url = `https://www.example.com/#page=${i}`;``` – T.J. Crowder Dec 11 '19 at 14:45
  • is this puppeteer? where are you defining `asins_page`? you should have the `url` correctly as an argument, I am not a 100% sure on your $$eval statement though – Icepickle Dec 11 '19 at 14:45
  • 4
    what is `undefined` and when – messerbill Dec 11 '19 at 14:45
  • the "page: undefined" – sparkle Dec 11 '19 at 14:46
  • Does this answer your question? [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – messerbill Dec 11 '19 at 14:48
  • Ok, I want to have the outer for loop into my hash – sparkle Dec 11 '19 at 14:51
  • 1
    what a strange dupe target, where is OP trying to modify a variable inside an asynchronous function and use it outside? – Klaycon Dec 11 '19 at 14:51
  • I don't want to modify it. I just need to access it. I updated the code to be clearer – sparkle Dec 11 '19 at 14:53
  • @sparkle the problems are very similar to each other...and now you changed the code example as well – messerbill Dec 11 '19 at 15:03
  • 1
    @T.J.Crowder I checked the linked post, but in my case I don't need to modify the outerscopevar, just need to access it. – sparkle Dec 11 '19 at 15:09
  • 1
    @sparkle - Sorry about that! Removed the comment. But something weird is going on, because `i` is **definitely** accessible there. Please update your question with a [mcve] demonstrating the problem, ideally a **runnable** one using Stack Snippets (the `[<>]` toolbar button; [here's how to do one](https://meta.stackoverflow.com/questions/358992/)). (Please `@` ping me when you do so I can vote to reopen.) – T.J. Crowder Dec 11 '19 at 15:12
  • @T.J.Crowder Thank you. I have updated the code. – sparkle Dec 11 '19 at 15:16
  • OK, what you posted *should* work with respect to `i`. `ReferenceError: i is not defined` should not show up when executing `div => ({ page: i })` because the variable would be visible there. I don't know what `page.$$eval` does but I suspect *that* might be throwing an error and the name `i` is more of a coincidence. Can you try changing that to `page: 1` or some other constant? Does it still throw an error? – VLAZ Dec 11 '19 at 15:27
  • @VLAZ yes, with a constant it works. page:1 – sparkle Dec 11 '19 at 15:29
  • Oh! This is Puppeteer code! You have to remember that the code within `$$eval` is run in a completely different place than the code surrounding it. So yes, there's no `i` in scope where that code runs. See [this answer](https://stackoverflow.com/a/58333846/157247) and [the docs](https://github.com/puppeteer/puppeteer/blob/master/docs/api.md#pageevalselector-pagefunction-args) for what to do. Basically: https://pastebin.com/JQbv0Tgp or similar. – T.J. Crowder Dec 11 '19 at 15:38
  • 1
    @sparkle *weird*. In that case, I'd guess that maybe `$$eval` is doing something odd. Looking at [this](https://stackoverflow.com/questions/51280984/how-to-use-eval-function) the second argument is a callback that's going to be evaluated in the context of the page. I suspect that perhaps $$eval is stringifying the function and then calling (essentially) `eval("divs => divs.map( div => ({ page: i })")` which will lose access to `i`. According to the answer there, the *third* argument to `$$eval` is an argument you can pass to the function. – VLAZ Dec 11 '19 at 15:39
  • 1
    So you should probably pass `i` there but I'm not sure how you would need to restructure the function itself to use that argument. Perhaps `page.$$eval( '[data]', (divs, i) => divs.map( div => ({ page: i }), i )`? – VLAZ Dec 11 '19 at 15:39
  • @T.J.Crowder ah, damn. Was writing my double comment and puzzling over the documentation (*which doesn't explain how to use `...args`*. Grr!) and you beat me to it. Seems my guesswork was right, at least. – VLAZ Dec 11 '19 at 15:41
  • Thank you all! I tried with the @VLAZ and it's works! If you past it as an answer i will accept it! Thank you! :) – sparkle Dec 11 '19 at 15:44
  • 1
    We can't post answers to closed questions. We should update the close reason to a duplicate of [the question I linked above](https://stackoverflow.com/questions/58329637/javascript-closure-and-async-function-arguments) but unfortunately SO makes that difficult. Anyway, you're sorted out now! Happy coding! – T.J. Crowder Dec 11 '19 at 15:57
  • @VLAZ - Yeah, the lack of an example of using args just seems really wrong. I suppose if one had time, one could do a PR... – T.J. Crowder Dec 11 '19 at 15:57

0 Answers0