Home > Software design >  Is it possible to map through an array and fetch data from a server for each item gotten from the ma
Is it possible to map through an array and fetch data from a server for each item gotten from the ma

Time:08-14

Data consists of an array of posts made by different users in the database. Each post holds the _id of the user who made the post. I want to map through each post, get the _id of the post and fetch the user data for each post. this is how far I've gotten. is there a proper way to do this or a better way? I'm running into errors.

    const getUsers = () => {
    data.map(async () => {
        await axios({
        method: "POST",
        withCredentials: true,  url:`https://droplikebackend.herokuapp.com/api/user/get/${id}`,
        data: {
            userId: data.userId,
        },
      })
        .then((res) => {
          console.log(res.data);
        })
        .catch((err) => {
          console.log(err);
        });
    });
  };

CodePudding user response:

What will work best is to extract the exact getUser logic in a separate function. What im not sure about is why method is "POST" and why id of the user is in both, the URL and in data property in axios.

No need for .then and .catch as you can see, but if you want to catch something - just use a normal try/catch block, dont mix async/await with .then.catch:

const getUser = async (userId) => {
  const response = await axios({
    method: "POST",
    withCredentials: true,
    url: `https://droplikebackend.herokuapp.com/api/user/get/${userId}`,
    data: { userId: userId }
  });
  return response.data;
};

Now about usage - the map function in this case will return an array of Promises, as you can see, and you can use Promise.all() method to await them all and get the results. All the promises will fire simulateously and not one by one if it was a for loop with awaits. Cons: if your API has rate-limiter - you can get banned for a while, Because for 100 posts 100 getUser requests will be fired in a less than a second.

const getUsers = async () => {
  const promises = data.map((post) => getUser(post.userId));
  const users = await Promise.all(promises);
  return users;
};

CodePudding user response:

app.js

const axios = require("axios");
const getUsers = async (id) => {
  const data = await axios({
    method: "get",
    url: id // if exist id search for id, if not exist map of restult
      ? `https://jsonplaceholder.typicode.com/posts/${id}`
      : "https://jsonplaceholder.typicode.com/posts"
  });

  if (id) {
    // if exist an id return a object and not array
    return console.log(data.data.id);
  } else {
    // map the array
    data.data.map((post) => console.log(post.id));
  }
};

getUsers(); // all post
// getUser(1) only bring the post with id 1

You can´t use data.map because data is not defined before, you can validated if the function bring an id or not and come all post or only one post. I used JsonPlaceHolder becuase your api is an post. but is the same. In my example with only find on post is and object, you can pass an array and with hat isn't necessary validated if is a object or array and the data.map will work fine You don't can use data.map because data is not defined before, you can validated if the function bring an id or not and come all post or only one post. I used JsonPlaceHolder becuase your api is an post. but is the same. In my example with only find on post is and object, you can pass an array and with hat isn't necessary validated if is a object or array and the data.map will work fine

CodePudding user response:

[
    {
        "_id": "62f45046a763042f5f35ba06",
        "userId": "62eb470392306d95ed89d964",
        "Image": "",
        "caption": "Monday!",
        "likes": [],
        "comments": []
    },
    {
        "_id": "62f4504ea763042f5f35ba08",
        "userId": "62eb470392306d95ed89d964",
        "Image": "",
        "caption": "Tuesday!",
        "likes": [],
        "comments": []
    }
]

This is what the data looks like. I want to display the username of the users who made these posts and I can only do that by fetching their individual data from the userId attached to the post.

  • Related