1

I have sample code as following.

var getPostedData =  function (request) {
    var qs = require('querystring');
    var body = '';
    request.on('data', function(chunk) {
        body += chunk.toString();
    });     
    return qs.parse(body);
};
getPostedData();

But the connection request data is coming as stream or multiple data packets. It cannot be returned as like above code in node v0.12. The sample code will work with node v0.10.

One solution to multiple data packets is to listen end event emit on request object.

var getPostedData =  function (request) {
        var qs = require('querystring');
        var body = '';
        request.on('data', function(chunk) {
            body += chunk.toString();
        }).on('end', function() {
            //Here body will have multiple data packets
            //return qs.parse(body);
        });     
        return qs.parse(body);
    };
    getPostedData();

But here we can't get return value because of asynchronous nature. How to return full multiple data chunks in a function/method?

Justin John
  • 9,223
  • 14
  • 70
  • 129
  • @Bergi This is not a duplicate of the question linked. It's related, not exact duplicate. The scenario that need to be handle have difference in server side javascript and client side javascript. – Justin John Jul 30 '15 at 19:31
  • Whether it's an ajax `onload` response or an eventemitter `onend` value, both are about "returning" a value from an asynchronous callback. The solutions (callback, promise) are exactly the same. – Bergi Jul 30 '15 at 19:32
  • @Bergi The post says that sample code works in older version of node, not in newer one. It shows difference. I don't see similar ajax behaviour. – Justin John Jul 30 '15 at 19:42
  • Uh, I'm pretty sure it didn't work with node v0.10 either (`request` hardly ever was synchronous, like sjax). If you will focus ([edit]) your question on why it worked with 0.10 but no more with 0.12 I can reopen it, but currently it just asks how to make it work which is answered by the dupe – Bergi Jul 30 '15 at 19:46
  • Maybe a better duplicate: [How to ensure asynchronous code is executed after a stream is finished processing?](http://stackoverflow.com/q/30465092/1048572) – Bergi Aug 01 '15 at 21:26

1 Answers1

2

You just need to add a callback function to know when the job done in async.

var getPostedData =  function (request, callback) {
    var qs = require('querystring');
    var body = '';
    request.on('data', function(chunk) {
        body += chunk.toString();
    }).on('end', function() {
        callback(null, qs.parse(body));
    }).on('error' function(err){
        callback(err);
    });
};

router.post("/example", function(req, res, next){
  getPostedData(req, function(err, body){
    if(err) return next(err);
    req.body = body;
    next();
  });
}, function(req, res){
  console.log(req.body);
  // Do you favor
});

At there I user your getPostData function as a middle-ware on /example router.

greenlikeorange
  • 505
  • 3
  • 10
  • Thank you @green. I would like to do this in synchronous style without a callback. Is there any way do so? – Justin John Jul 30 '15 at 18:09
  • 1
    @JustinJohn you can use [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), that is another way of handling callbacks. Then nature of nodejs is already async I/O so you can't do synchronous without callback/promise. – greenlikeorange Jul 30 '15 at 18:14
  • @JustinJohn or you could use `async` for that (see this answer http://stackoverflow.com/questions/31729135/how-to-ensure-an-asynchronous-call-is-executed-before-returning-from-a-function/) – Gepser Hoil Jul 30 '15 at 18:16
  • @JustinJohn I not recommend to use `async` at that point (`getPostedData`), because it already in event loop **(promise)**, example `on('data', callback)`. – greenlikeorange Jul 30 '15 at 18:30