Steve
Steve

Reputation: 1423

Playwright pass variable into eval with JavaScript (Node)

Note: this is for Playwright, the browser API, like puppeteer.

I'm trying to find all elements on a page, then want to filter those elements down into values. The values have specific selectors on them (css classes, etc). The problem I have is that I cannot pass outside variables into the $$eval function so that my CSS selectors can be dynamic.

EG:

    const cardsPerPage = await page.$$eval('.ais-hits--item', (repoCards) => {
      return repoCards.map(card => {
        const name = card.querySelector('a.product-thumbnail__title'); // < this is the problem
          return {
            name: toText(name),
          };
        });
     });

If I try to change my CSS selector to a variable it doesn't work, I've tried just about everything.

    const customSelector = 'a.product-thumbnail__title';
    const cardsPerPage = await page.$$eval('.ais-hits--item', (repoCards) => {
      return repoCards.map(card => {                            
        const name = card.querySelector(customSelector); // < this is the problem
          return {
            name: toText(name),
          };
        });
     });

The error is:

    error: page.$$eval: ReferenceError: customSelector is not defined
          at eval (eval at evaluate (:3:2389), <anonymous>:4:57)
          at Array.map (<anonymous>)
          at eval (eval at evaluate (:3:2389), <anonymous>:2:38)
          at t.default.evaluate (<anonymous>:3:2412)
          at t.default.<anonymous> (<anonymous>:1:44)
          at Scraper.main (/home/steve/dev/test/src/scraper/index.js:67:49)

Upvotes: 1

Views: 2527

Answers (1)

Fung
Fung

Reputation: 7780

You'll need to do something like

const customSelector = 'a.product-thumbnail__title';
const cardsPerPage = await page.$$eval('.ais-hits--item', (repoCards, selector) => { // Your selector from ➀ becomes the last param of your evaluated lambda
  return repoCards.map(card => {                            
    const name = card.querySelector(selector);
      return {
        name: toText(name),
      };
    });
 }, customSelector); // ➀ Your selector is passed in as the arg param

Additionally, if toText was declared outside of $$eval which it seems to be, then you'll get an error for that, too.

Upvotes: 1

Related Questions