Home > Software design >  Empty Array returned and not being populated when pushing objects
Empty Array returned and not being populated when pushing objects

Time:06-21

I am using Node JS and Express JS, here is my controller code:

const UserComment = require("../model/UserComment");


router.post("/get/comments", async (request, response) =>{
try{
    let currentUserID = request.body.userID;
    let myUserComment = await UserComment.find({userID: currentUserID});        
    let friendsCommentsArray = [ ...myUserComment];

    let friendsComments = await axios.post(`http://localhost:5000/router/accounts/account/following/list`, {userID: currentUserID})
        .then((resp) => {
            resp.data.message.map((parentArrayOfArray) =>{
               
                parentArrayOfArray.map((friendID) =>{
                    let friendsCommentsToLookUp = UserComment.find({userID: friendID})

                    friendsCommentsToLookUp.then((commentsArray) =>{
                        commentsArray.map((comment) =>{
                            if(String(comment.userID) === friendID){

                                friendsCommentsArray.push(comment);
                               
                                
                            }else{
                            
                                console.log("no")
                            }
                        })
                    });
                    
               });
            });

        }).catch((err) =>{
            console.log("err: ", err);
            throw err;

        });





  return response.status(200).json({message: friendsPostsArray}); 
          
 }catch(err){
    return response.status(400).json({message: `${err}`});

}
});

The friendsCommentsArray, when I console.log it I can see the data, but when I return it, it’s empty. What is the problem, why is it empty, even though i'm pushing every comment iterated over to the friendsCommentsArray.

However, the returned friendsCommentsArray is empty. how to solve this issue ?

Thanks.

CodePudding user response:

To make await Promise.all() work you need to return the promise

return axios.get(`http://localhost:5000/comments/by/post/${post._id}`)

CodePudding user response:

Generally when you use await, you don't need to use .then(). Your problem is that your inner .map() is using friendsCommentsToLookUp.then(), but nothing is waiting for these promises to resolve before you move on in your code. One might think that you can await the friendsCommentsToLookUp promise, but this won't work, as the calls to the map callback are not awaited.

Removing the .then()'s makes this easier to work with:

const resp = await axios.post(`http://localhost:5000/router/accounts/account/following/list`, {userID: currentUserID});
const message = resp.data.message;
for(const parentArrayOfArray of message) {
  for(const friendID of parentArrayOfArray) {
    const commentsArray = await UserComment.find({userID: friendID});
    for(const comment of commentsArray) {
      if(String(comment.userID) === friendID){
        friendsCommentsArray.push(comment);
      }
    }
  }
}

Above the for..of allows us to pause moving to the next iteration of the for loop until the Promises within the current iteration of the for loop have resolved. ie: it's sequential (note: if you tried to do this with .forEach() or .map(), your code would proceed directly to the portion after the loop before your Promises have resolved). Although, what you're after doesn't need to be sequential. We can create an array of Promises that we pass to Promise.all() which we can wait to resolve in parallel. Below I've shown a different approach of using .flatMap() to create an array of Promises that we can await in parallel with Promise.all():

const resp = await axios.post(`http://localhost:5000/router/accounts/account/following/list`, {userID: currentUserID});
const message = resp.data.message;
const promises = message.flatMap(parentArr => parentArr.map(async friendID => {
  const commentsArray = await UserComment.find({userID: friendID});
  return commentsArray.filter(comment => String(comment.userID) === friendID);
}));
const nestedComments = await Promise.all(promises);
const friendsCommentsArray = [...myUserComment, ...nestedComments.flat()];

CodePudding user response:

instead of push try concatenation array and let me know if its work.

friendsCommentsArray = [...friendsCommentsArray , {...comment}];
 // insted of
friendsCommentsArray.push(comment);

also try to use forEach instead of map() while you don't want to return a new array from your map statement.

The map method is very similar to the forEach method—it allows you to execute a function for each element of an array. But the difference is that the map method creates a new array using the return values of this function. map creates a new array by applying the callback function on each element of the source array. Since map doesn't change the source array, we can say that it’s an immutable method.

  • Related