Search code examples
javascripttypescriptes6-promiseplaywright

Await an array of Promises mapped from Object entries


With the following snippet code the function should await all the promises mapped from the Object entries node. For instance the $eval function comes from the Playwright library and throws an error due to the fact that the target document in which the evaluate is performed will be closed by the time that the promises should be awaited.

The above error can be fixed by nesting another await Promise.all but I'm not getting why the external await Promise.all is not properly handling the inner loop given that I'm returning an array of Promise

const tableBodyRows = await page.locator(`tbody >> tr`).elementHandles()
      await Promise.all(
        tableData[pageIndex].map(async ({ node }, idx) => {
          // await Promise.all(
            return Object.entries(node).map(async ([key, val]) => {
              const cellText = await tableBodyRows[idx].$eval(
                `td.${key.toLowerCase()}`,
                (cell: HTMLTableCellElement) => cell.textContent,
              )
              return expect(cellText).toEqual(val)
            })
          // )
        }),
      )

Solution

  • As the others have said - you are returning an array of arrays. If your target is es2019 or later - you can replace the map call, with flatMap

    const tableBodyRows = await page.locator(`tbody >> tr`).elementHandles()
          await Promise.all(
            tableData[pageIndex].flatMap(({ node }, idx) =>
               Object.entries(node).map(async ([key, val]) => 
                  expect(await tableBodyRows[idx].$eval(
                    `td.${key.toLowerCase()}`,
                    (cell: HTMLTableCellElement) => cell.textContent,
                  )).toEqual(val)
               )
            ),
          )