1

I am having some trouble finding a way to get this to work. Basically I get a list of users from a mock api endpoint and what I want to do is actually map each user to only have an email.

// returns 10 users from mock api so we have something to work with
function getUsers() {
  return fetch('https://jsonplaceholder.typicode.com/users')
    .then(res => res.json())
    .then(data => {
      console.log(data)
      return data
    })
}

// this just gives us something to map over
const usersList = getUsers()


// get specific user by id e.g. /users/1
const mappedUsers = (users) => {
    return users.map(async user => {
      // get a specific user by id
      const response = await fetch(`https://jsonplaceholder.typicode.com/users/${user.id}`)
      const userData = await response.json()

      // and only return the email property from the api reponse for each user
      return {
        userEmail: userData.email
      }
    })
}

mappedUsers(usersList)

The end result should just look like this:

mappedUsers = [
  { userEmail: 'name of the first email from api' },
  { userEmail: '...' },
  ...
]
7
  • 3
    Thanks for including enough code for us to clearly see the problem, you'd be surprised how often people don't do that. :-) userList will be a promise, not an array. You have to hook into the settlement of the promise and then use the fulfillment value. Similarly, mappedUsers will be an array of promises, so you have to wait for the promises to settle (usually by using Promise.all) and then access their fulfillment values. See the answers to the linked questions for details. Commented Nov 2, 2022 at 12:11
  • 1
    Side note: Your code is falling prey to the footgun in the fetch API I describe here (my anemic old blog). fetch only rejects its promise on network errors, not HTTP errors. You have to check for HTTP errors on purpose (by checking ok on the response before reading the response body). Commented Nov 2, 2022 at 12:12
  • Got it thanks, I will check into this deeper. I had a feeling something was bad using await each time because each iteration would be pausing essentially. Commented Nov 2, 2022 at 12:16
  • 1
    Nope, that's fine. :-) map does its work synchronously. When you call an async function, it's synchronous up until the first await, return, or throw; at that point, the function returns a promise. So map synchronously starts each fetch and builds an array of the promises, allowing the network operations to run in parallel. Commented Nov 2, 2022 at 12:20
  • 1
    It would look something like this (though there are several ways to do it): jsfiddle.net/tjcrowder/2zdpxmha/1 Commented Nov 2, 2022 at 13:05

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.