AdamSulc
AdamSulc

Reputation: 450

Array.filter() with async arrow function

I am trying to filter my array using Array.filter() function, however I came across this issue. I need to call some other function inside the filter function asynchronously. However the array is not changing its value based on the conditions that I define in the function.

const filterWithEmail = data.filter(async (doc) =>
{
   const findUser = await UserService.findUser(doc.id).catch(err => {});
   if (findUser)
   {
      const { email } = findUser;
      return regexFilter ? regexFilter.test(email.normalize("NFKC")) : false;
   }
});

This code doesn't affect the data array at all for some reason. Any suggestions what I'm doing wrong?

Thank you in advance.

Upvotes: 1

Views: 2203

Answers (1)

Quentin
Quentin

Reputation: 943217

filter expects the return value of the callback to be a boolean but async functions always return a promise.

You don't know if you want to return true or false in time to tell filter which it is.

What you possibly want to do is:

  1. map the data from data to { keep: true, original_data: data } (using an async callback)
  2. Pass the resulting array of promises to Promise.all
  3. await the return value of Promise.all
  4. filter that array with: .filter(data => data.keep)
  5. Get the original objects back with .map(data => data.original_data)

Something along these lines (untested):

const filterWithEmail = (
  await Promise.all(
    data.map(async (data) => {
      const findUser = await UserService.findUser(doc.id).catch((err) => {});
      let keep = false;
      if (findUser && regexFilter)
        keep = regexFilter.test(email.normalize("NFKC"));
      return { data, keep };
    })
  )
)
  .filter((data) => data.keep)
  .map((data) => data.data);

Upvotes: 4

Related Questions