0

Hi i am a newbie on nodejs I was trying to implement a project in which we have to event management site..where we are adding event to the page for a specific user.

Now the problem is i am getting stuck at this point:-

   exports.getDashBoard=function(req,res){
    var eventList=[];
       for(var i=0;i<req.user.invites.length;i++)
       {
                   Event.find({_id:req.user.invites[i]},function(err,events){
                   if(err)
                   {
                   console.log(err);  
                   }
                   else
                   {
                    eventList.push(events[0]);
                    console.log(eventList);
                    // shows value inside the array as wanted
                   }
                 });
       }
    console.log(eventList);
                // shows null value why? the variable is in the scope as its declaration 

   res.render('dashboard');
   };

Explanation: I created a function in which i have the variable eventList declared and initialized every time the function gets called. I used this variable eventList Inside a inner function to update its value and concatenate to the previous values.. The console.log shows that the eventList is getting updated as wanted.But when i try to use this variable outside the the inner function is doenst work and i get a empty array as initialized The scope of the variable is local is in the main function and is visible inside the inner funciton but when i use it after the inner funciton ie outside the for loop the array shows null value What to do?

the image below:- I created a function in which i have the variable eventList declared and initialized everytime the function gets called. I used this variable eventList Inside a inner function to update its value and concatenate to the previoys values.. The console.log shows that the eventList is getting updated as wanted.But when i try to use this variable outside the the inner function is doenst work and i get a empty array as initialized The scope of the variable is local is in the main function and is visible inside the inner funciton but when i use it after the inner function the vanishes

What to do?

enter image description here

3 Answers3

0

You are printing eventList before it actually gets populated. You are appending items to eventList inside the Event.find callback that might not have executed yet when you do the outer console.log(eventList);.

Edit:
To print the collection once all callback are called you can check in the callback if you are in the last iteration, if so, print eventList.

if(i===(req.user.invites.length-1)){
    console.log(eventList);
}

You could/should also consider something more elaborated as async.js or some promise library (as Q). With async.js your code would look something like (not tested):

async.eachSeries(req.user.invites, function (invite, callback) {
  Event.find({_id:invite}, function(err,events){
    if(err) {
      console.log(err);
      throw err;   
    } else {
      eventList.push(events[0]);
      console.log(eventList);
    }
  }
}, function (err) { // called once all iteration callbacks have returned (or an error was thrown)
  if (err) { throw err; }
  console.log(eventList); // Final version of eventList
});
mziccard
  • 2,158
  • 9
  • 17
  • .I uderstand that but i want to display all the events and it is possible after the callback is fully executed.I have no idea how to do it.Can you please help me –  Jul 02 '15 at 07:55
  • @PrathameshP I edited my answer to give some more details – mziccard Jul 02 '15 at 08:16
0

The Console.log is called before your loop finishes.

You could check within your inner function for the last loop and call when true:

if(err)
{

    console.log(err);  
}
else
{

    eventList.push(events[0]);
    console.log(eventList);
    // shows value inside the array as wanted

// Check if its the last loop, if so, print eventList
if(i==(req.user.invites.length-1)){

    console.log(eventList);
}

}

Stacey Burns
  • 1,092
  • 7
  • 14
0

shows null value why? the variable is in the scope as its declaration

for(var i=0;i<req.user.invites.length;i++)
       {
   // time taking task. probably db call.         
}
console.log(eventList); 

This is because js is asynchronous.

In your for loop their exist a time consuming task, so the js pointer will move to next line(console.log) once the for loop iterations are over. Note: only iterations are over yet, but tasks are still in progress, their callbacks will be called later when these task will get completed.

Simulation:

function(){
    for(var i =0;i<5;i++){
        setTimeout(function(){
            console.log('time taking task is over now.');
        }, 100);
    }
    console.log('I am after for loop');
}

Here, output would be like following:

I am after for loop
time taking task is over now.
time taking task is over now.
time taking task is over now.
time taking task is over now.
time taking task is over now.

In nutshell, you need to manage your workflow by figuring out which all tasks are time consuming task and which all tasks are dependendent on them. Put all those dependent tasks in the callback of the task (This approach although solves the problem but as requirements extends this give rise to new problem of Callback hell/pyramid of doom. See promises for over coming callback hell).

Also, you can use workflow management library like async, which will manage the workflow for you.

Community
  • 1
  • 1
Gaurav Gupta
  • 4,586
  • 4
  • 39
  • 72