PanzerMoonbeam
PanzerMoonbeam

Reputation: 11

How to wait for Promise.all to resolve before returning values in async function (express JS)

I'm pretty new to JS and especially async programming. I am trying to build an Express+React app that displays a gitHub user's info (including a few repos with 5 commits).

To do the latter, I am using Promise.all and map to get the commits for each repo in an array, and returning an array with the commits added to each repo.

When I console.log the new repo in the map function, it works, but when I try to return the array, the objects are undefined.

I assume this is because the return is executing before the Promises have resolved. Can anyone help me out with this?

//takes a username and collection of repos and finds their commits using fetch to github API. Returns the array of repos with their commits as a new property
const getGitHubCommits = async (username, repos) => {
  try {
    const repositories = await Promise.all(
      repos.map(async (repo) => {
        fetch(`https://api.github.com/repos/${username}/${repo.name}/commits?per_page=5`).then(response => response.json())
          .then(async response => {
            repo.commits = response.slice(0, 5)
            console.log(repo)
            return await repo
          })
      })
    );

    console.log(repositories)
    return repositories
  } catch (error) {
    console.log(error)
    return "No commits found found"
  }
}

Upvotes: 1

Views: 34

Answers (1)

Ilijanovic
Ilijanovic

Reputation: 14904

You dont need async / await here at all. As soon as you put async infront of an function, the function will return an promise and you need to resolve that promise then.

Here is a better version:

const getGitHubCommits = (username, repos) => {
  return Promise.all(
    repos.map((repo) =>
      fetch(
        `https://api.github.com/repos/${username}/${repo.name}/commits?per_page=5`
      )
        .then((response) => response.json())
        .then((response) => {
          repo.commits = response.slice(0, 5)
          return repo
        })
    )
  )
}

This is much cleaner. Later you need to resolve the promise:

getGitHubCommits('...', ['...'])
  .then((result) => {
    console.log(result)
  })
  .catch((err) => {
    console.log(err)
  })

Or you can use here async / await if you call it inside an async function:

try {
  let commits = await getGitHubCommits('..', ['..'])
  console.log(commits)
} catch (err) {
  console.log(err)
}

Upvotes: 1

Related Questions