I am new to node.js and not able to understand the concept of callback and async.parallel.I am trying to run the below node.js code in APIGEE.It is giving me an error saying callback is not define.
var request = require('request');
var async = require('async');
var express = require('express');
var urlparse = require('url');
var util = require('util');
var app = express();
var merge= require('underscore');
var http = require('http');
var myJson;
var myJson1;
var address_ups;
function sendError(resp, code, msg) {
var oa = { 'error' : msg };
resp.writeHead(code, {'Content-Type' :'applicationjson'});
resp.end(JSON.stringify(oa));
}
var svr = http.createServer(function(req, resp) {
var parsed = urlparse.parse(req.url, true);
var postalcode=parsed.query.postalcode;
if (!parsed.query.postalcode) {
sendError(resp, 400, 'Missing query parameter postalcode');
} else {
async.parallel([
function ups(postalcode,callback) {
request('URL1', function(err, result, body) {
if (err) {
sendError(resp, 400,
util.format('Error response %s from geocoding web service', err.message));
//cb(err);
return;
}
else
{
profile = JSON.parse(body);
}
});
callback(postalcode,profile);
},
function dhl(postalcode,profile,callback) {
request('URL2', function (err, result, body) {
if (err) {
sendError(resp, 400,
util.format('Error response %s from elevation web service', err.message));
callback(err);
return;
}
else
{
profile1 = JSON.parse(body);
var profile3={'ups':profile,'dhl':profile};
}
});
callback(profile3);
}
], function(err,profile3) {
if (err) {
resp.status(500).send('Ouch,We had a problem!');
//throw err; //Or pass it on to an outer callback, log it or whatever suits your needs
}else{
//o={'UPS':UPS,'DHL':DHL};
resp.writeHead(200, {'Content-Type' :'applicationjson'});
resp.end(JSON.stringify(profile3));
}
//console.log('Both a and b are saved now');
});
}
});
svr.listen(9000, function() {
console.log('Node Mashup sample app is running on port 9000');
});
Please bear with the code its not clean.
Kindly also explain the concept of async.parallel and callbacks in Node.js.
Check the type of postalcode in your first function like this:
console.log(typeof postalcode); // function?
I expect it is function. i.e. the callback function.
For async.parallel you should not pass any arguments other than callback. The parallel functions are being executed at the same time so you can't pass data from one to the other!
Even if you are using something that does take arguments such as async.waterfall, the first function argument takes only a callback.
Typical use for waterfall:
async.waterfall([
function (callback) { callback(arg1); },
function (arg1, callback) { callback(); }],
function (err) {});
And in parallel:
async.parallel([
function ups (callback) {
// happening at the same time so nothing to pass!
callback();
},
function (callback) {
callback(); //etc.
}],
function (err) {});
In your case you are generating
i.e. Change your code to do the following:
var postalcode = "12345"; // This is available globally
// inside waterfall functions
async.waterfall([
function (callback) {
// generate some new profile data ...
request('URL1', function(err, result, body) {
if (err) {
sendError(resp, 400,
util.format('Error response %s from geocoding web service', err.message));
callback(err); // errors are passed back first.
return;
}
// Return callback inside request function!
profile = JSON.parse(body);
// for next funciton null will be ignored, profile is taken as
// first argument
callback(null, profile);
});
},
function (profile, callback) {
request('URL2', function (err, result, body) {
if (err) {
sendError(resp, 400,
util.format('Error response %s from elevation web service', err.message));
// error so pass back non-null first argument.
callback(err);
return;
}
profile1 = JSON.parse(body);
var profile3={'ups':profile,'dhl':profile};
// Again. callback inside request callback body.
// null first because there is no error
callback(null, profile3);
});
}],
function (err, profile) { // etc
})