Nilesh
Nilesh

Reputation: 55

How to get rid of the asynchoronous code here

I have been trying to retrieve the data using the MongoJS driver for node.js.The Code which I am using is as follows

     req.on('end', function(){
             var decodedBody = querystring.parse(fullBody);
             story=decodedBody.name;
             var z=new Array();
             console.log(story);
         res.writeHead(200,{'Content-Type': 'text/html'});
         res.write('<html><body>');
             db.frames.find({str_id:story}).toArray(function(err,doc){
             console.log(doc);
             for(var t=0;t<doc.length;t++)
                 {
                     var picid=doc[t].pic_id;
                     console.log(picid);               
                     db.pictures.find({_id:picid}).toArray(function(err,pic){
                      res.write('<img src="'+pic[0].name+'"/>');
             });
           } 
        }) 
        res.end('</body></html>'); 
   });

The problem here is that because of the asynchronous nature of the code the response gets ends first and then the code inside the block of database gets executed and because of that nothing gets displayed on the browser i.e an image in this case .Thankx in advance.

Upvotes: 2

Views: 123

Answers (2)

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230561

Don't fight the asynchronous nature of node.js, embrace it!

So you should fire off all your requests, marking each one as completed when the response arrives. When all requests are completed, render your images and body/html closing tags.

I don't usually work with node.js, so I can make some mistakes, but it may look like this:

res.write('<html><body>');
db.frames.find({str_id:story}).toArray(function(err,doc){
  console.log(doc);

  var completed = {};

  for(var t = 0; t < doc.length; t++) {
    var picid = doc[t].pic_id;
    completed.picid = false;
    console.log(picid);               
    db.pictures.find({_id: picid}).toArray(function(err, pic) {
      // mark request as completed
      completed.picid = pic;


      // check if all requests completed
      var all_finished = true;
      for(var k in completed) {
        if(completed[k] === false) {
          all_finished = false;
          break;
        }
      }

      // render final markup
      if(all_finished) {
        for(var k in completed) {
          var pic = completed[k];
          res.write('<img src="'+pic[0].name+'"/>');
        }
        res.end('</body></html>);
      }
    });


  } 
}) 

Upvotes: 3

zemirco
zemirco

Reputation: 16395

just put the res.end('</body></html>'); inside your db.frames.find function. Check when you reached doc.length - 1 and then send the end command.

Upvotes: 1

Related Questions