Reputation: 110
I know node is all about async stuff but I want to do things in serial mode as follows:
make api request > convert body xml to JSON.stringify > pass string to template.
request.get({url:url, oauth:oauth}, function(err, res, body){
parseString(body, function(err, result){
output = JSON.stringify(result);
res.render('home', { title: 'Fantasy Home',
output: output });
});
});
Now I want to do this in sequence, but with all the callbacks I'm confused.
res.render doesn't work nested inside callbacks because the res object doesn't exist. Having it outside won't work because it'll run before the callbacks execute so you'd get "undefined" for output.
There has to be a way to do things in sequential order. Why is everything a callback?? Why can't these functions just return a regular non-callback result?
How can I make this work?
Upvotes: 0
Views: 233
Reputation: 9136
The others fail to mention why your res.render
does not work.
You probably have something like this:
app.get('/', function(req, res, next) { // You need the res here to .render
request.get({url:url, oauth:oauth}, function(err, res, body){ // But you are using this res instead, which does not have the render method
parseString(body, function(err, result){
output = JSON.stringify(result);
res.render('home', { title: 'Fantasy Home',
output: output });
});
});
});
Read the comments in the code. So your solution is, use res.render
from the request handler, rename res
in the request.get
callback to something else.
Upvotes: 1
Reputation: 774
JavaScript is single threaded if we use synchronous code then that will itself a big problem around response time (node.js) and all. Everything is implemented with callback fashion due to the benefit of event loop.
You can take a deep understanding of event loop : https://youtu.be/8aGhZQkoFbQ (Very good explaination)
You can use Promisification for the scenario you want to implement : http://bluebirdjs.com/docs/getting-started.html
request.get({url:url, oauth:oauth}, function(err, res, body) {
// Note :: This is Promisified Function
return parseString(body)
.bind(this)
.then(function(result) {
output = JSON.stringify(result);
res.render('home', {title: 'Fantasy Home', output: output });
return true;
})
.catch(function(error)
{
// Error Handling Code Here
// Then send response to client
});
});
You can implement promisified function using the following approach
function parseString(body) {
var Promise = require("bluebird");
return new Promise(function(resolve,reject) {
// Your Parsing Logic here
if(is_parsed_successfully) {
return resolve(parsed_data);
}
return reject(proper_err_data);
})
}
Upvotes: 0
Reputation: 411
You should use middlewares, also promises is better thing to work with async in node, but I'll show you with callbacks. It is strongly suggested to not to block your thread with synchronous calls! Since node.js is single threaded. next()
is an callback here so middleware won't allow execution of main route function (with res.render) until next() is called. You can pass as many middlewares as you wish.
app.use('/user/:id', middleware, (req, res) => {
//here you'll find your data
console.log(req.callData);
res.render(view, req.callData);
}
middleware(req, res, next) => {
dotheCall(dataToPass, (err, cb) => {
req.callData = cb;
// remember about handling errors of course!
return next();
})
}
Upvotes: 0