rocktimsaikia
rocktimsaikia

Reputation: 175

How to loop through an array via an async function inside another async function?

I am trying to call two apis with two async function.The thing is that the second
async function's api call depends upon the the result of the first async function.

  1. My first async function fetches some data from an api and returns an
    array(users) of objects .
  2. The second async function calls another api that takes the id property from
    each object of users as url parameter.and will returns a status for each
    object and we want to filter only those user that has status 204.

I know the logic on how to do this but can't implement it in real world.Plus
nested async functions always seems hard to me , here is my attempt :

    const getUsers = async () => {
        const { users } = await axios.get(url);
        return users;
    };

    const getCheckedUsers = async () => {
        const allUsers = await getUsers();
        const promises = allUsers.then(users => {
            users.map(async user => {
                const { status } = await axios.get(another_url_that_takes_`user.id`);
                if (status === "204") {
                    return user;
                }
            });
        });
        const results = await Promise.all(promises);
        return results;
    }

First function works fine i tested it separately.It returns the needed array.
But the issue starts when i try to combine first async function with the second
one.

Upvotes: 4

Views: 998

Answers (2)

3limin4t0r
3limin4t0r

Reputation: 21130

There are a few issues with your current code.

  1. You invoke .then on a non promise value (allUsers.then). This isn't needed because you already do const users = await getUsers() which will set users to the resolved value, not a promise.

  2. By using map and only returning the user if status equals "204", you will implicitly return undefined for users that have a status other then "204". If the intent is to leave out the values completely you can use filter on the users array.

const getUsers = async () => {
    const { users } = await axios.get(url);
    return users;
};

const getStatus = async (user) => {
    const { status } = await axios.get(`another_url_that_takes_${user.id}`);
    return status;
};

const getCheckedUsers = async () => {
    const users = await getUsers();
    const statuses = await Promise.all(users.map(getStatus));
    return users.filter((_, index) => statuses[index] === "204");
};

Upvotes: 1

Erick Petrucelli
Erick Petrucelli

Reputation: 14902

Using async/await there's no need to get lost with Promises since the code just runs line by line:

const getUsers = async () => {
  const { users } = await axios.get(url);
  return users;
};

const getCheckedUsers = async () => {
  const allUsers = await getUsers();
  const results = [];
  for (user of allUsers) {
    const { status } = await axios.get(`another_url_that_takes_${user.id}`);
    if (status === "204") {
      results.push(user);
    }
  }
  return results;
}

Upvotes: 1

Related Questions