Reputation: 1052
In this code, I'm trying to filter out parts of the ElementHandle array. The way I'm checking for if it works is by printing the length of the final filtered array. It should be 4, not 30.
const ar = await page.$$("li[class*=react-job-listing]");
const shortArray = Array.from(ar).filter(async (el)=> {
console.log((await (await el.getProperty("innerText")).jsonValue()).includes("Easy Apply"));
return (await (await el.getProperty("innerText")).jsonValue()).includes("Easy Apply");
});
//console.log((await (await ar[0].getProperty("innerText")).jsonValue()).includes("Easy Apply"));
console.log(shortArray.length);
console.log('hello');
Unforunately, this is the result.
30
hello
false
false
false
false
true
false
false
true
false
false
false
false
false
false
false
false
true
false
false
false
false
false
false
false
false
false
false
false
true
false
The console log for the length comes before the filter executes, when it should be the last thing.
It seems the script isn't waiting for the await. It must be due to the multiple nested awaits. But I don't know how to fix it.
I'm aware that this is really ugly. But there are some reasons I can't use page.evaluate and DOM functions right now. Please look over it for now.
Upvotes: 0
Views: 150
Reputation: 13772
It is not puppeteer fault. Async functions return Promise, so in Array.from(ar).filter()
each callbak returns thruthy value and nothing is filtered out. It is simpler and safer to use for..of
loops for async operations:
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
const html = `
<!doctype html>
<html>
<head><meta charset='UTF-8'><title>Test</title></head>
<body>
<p>foo 1</p>
<p>foo 2</p>
<p>bar 1</p>
<p>bar 2</p>
</body>
</html>`;
try {
const [page] = await browser.pages();
await page.goto(`data:text/html,${html}`);
const ar = await page.$$("p");
const shortArray = [];
for (const element of ar) {
const text = await (await element.getProperty("innerText")).jsonValue();
console.log(text, text.includes("foo"));
if (text.includes("foo")) shortArray.push(element);
}
console.log(shortArray.length);
console.log('hello');
} catch(err) { console.error(err); } finally { await browser.close(); }
foo 1 true
foo 2 true
bar 1 false
bar 2 false
2
hello
Upvotes: 1