1

Javascript - Node.js - Express - MongoDB - mongoose

I have a forEach() method that runs a for loop on each user adding/removing items in an array. It successfully adds the appropriate amount of items for one user, but fails to add the rest of the items. How is taskList.title 'undefined' with items remaining inside the Array?

User.find({}, function(err, allUsers){
    if(err){
        console.log(err);
    } else {
        console.log("Total Users: ", Number(allUsers.length));
        console.log("Users are: ", allUsers);
        Task.find({}, function(err, taskList){
            if(err){
                console.log(err);
            } else {
                console.log("Your task list: " , taskList);
                console.log("First item: " , taskList[0].title);

                let n = (Math.floor(Number(taskList.length) / Number(allUsers.length)));
                console.log("Users have", n , "items.");
                console.log("===============================");
                //assign n items to each user

               //line 151 
                allUsers.forEach(function addItem(user){
                    for(var i = 0; i < n; i++){
                        user.items.push(taskList[i].title);
                        taskList.splice(i,1);
                        console.log('item added!');
                        console.log(user.name+":", user.items);
                        console.log(taskList.length , "items remain.";
                    }
                });

            }
        });
    }
});


events.js:160
      throw er; // Unhandled 'error' event
      ^
TypeError: Cannot read property 'title' of undefined
    at addItem (/home/ubuntu/workspace/v1.4/app.js:151:56)
    at Array.forEach (native)
    at /home/ubuntu/workspace/v1.4/app.js:149:30
    at /home/ubuntu/workspace/v1.4/node_modules/mongoose/lib/model.js:4485:16
    at process.nextTick (/home/ubuntu/workspace/v1.4/node_modules/mongoose/lib/helpers/query/completeMany.js:35:39)
    at _combinedTickCallback (internal/process/next_tick.js:73:7)
    at process._tickCallback (internal/process/next_tick.js:104:9)
  • because you edit the array.... taskList.splice(i,1); So what do you think happens when you have a fixed endpoint and you remove items? – epascarello Aug 28 '18 at 20:28

1 Answers1

1

When you use TaskList.splice(i,1), you are updating the length of the TaskList array, but the for loop does not reference TaskList.length. You are using a cached value in n which is the original TaskList.length value.

You will either need to not use splice or use a different method of looping. Maybe something that uses Array.prototype.shift

var task;
while(task = TaskList.shift()) {
   ...
}
Jeremy Dejno
  • 106
  • 2
  • Agreed. Maybe omit the splice entirely as I'm not sure it's needed other than for calculating the remaining items in the console.log – cdimitroulas Aug 28 '18 at 21:47
  • Thanks everyone, I finally found a solution that works for me. I need to keep splice and the current loop. Iterate in reverse! https://stackoverflow.com/questions/9882284/looping-through-array-and-removing-items-without-breaking-for-loop – Evan D'Amico Aug 28 '18 at 23:22