-2

I am trying to learn more about asynchronous Javascript. Kindly help.

What I am trying to achieve - from the json place holder API, retrieve a list of posts; for each item in the posts array, retrieve the user details and then add the user details object to the posts array. I am executing this in a Node Js environment locally.

const fetch = require('node-fetch');

let toggleOne = true;

// Async function to retrieve the user details for a given user Id
const fetchUser = async (userId) => {
      const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`)
      const json = await response.json();
      return json;
}

const addUserDetails = (posts) => {
      return new Promise((resolve, reject) => {
            posts.map(post => {
                  fetchUser(post.userId)
                        .then(userDetails => {
                              // Print once to determine the sequence of operation
                              toggleOne ? console.log('Adding user.') : ''
                              toggleOne = false;

                              // add user details retrieved from fetchUser function to the posts object
                              post.userDetails = userDetails
                              return post
                        })
                        .catch(err => reject(err))
            })
            resolve(posts);
      })
}

// Async function to retrieve all posts
const fetchPosts = async () => {
      const response = await fetch('https://jsonplaceholder.typicode.com/posts');
      const posts = await response.json();
      return posts
}

fetchPosts()
      .then(posts => addUserDetails(posts))
      .then(postsWithUserDetails => {
            console.log(postsWithUserDetails[0])
      })
      .catch(err => console.log(err))

I am expecting the console.log(postsWithUserDetails[0]) to print below:

{
  userId: 1,
  id: 1,
  title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit',
  body: 'quia et suscipit\n',
  userDetails: { ... }
}

but its printing below which is the output of the first API request.

{
  userId: 1,
  id: 1,
  title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit',
  body: 'quia et suscipit\n'
}

I believe I am making an error and resolving the promise too early but not able to figure out how to get it to work.

Any suggestions would be greatly appreciated. Many thanks.

  • Use `for...loop` instead of `.map`. – hoangdv Jan 14 '23 at 04:44
  • Thank you - that worked as well. const addUserDetailsForLoop = async (posts) => { for (const post of posts) { const data = await fetchUser(post.userId); post.userDetails = data; } return posts } – Nemil Sheriff Jan 14 '23 at 09:12

1 Answers1

0

You are not returning the result of posts.map() which is the main issue. You're also resolving all the promises in the array.

Here's my version (untested, but hope it helps)

const addUserDetails = (posts) => {
  return Promise.all( 
    posts.map(async post => {
      const userDetails = await fetchUser(post.userId);
      post.userDetails = userDetails;
      return post;
    })
  })
}
Evert
  • 93,428
  • 18
  • 118
  • 189