Kobus Marais Kobus Marais - 26 days ago 9
JSON Question

Making async calls with nodejs and express

I have 2 functions, the first:

router.post('/getStances', function(req, res, next) {
var text = '{"success":"0"}';
text = queries.getStances(req.body.issues[0], req.body.issues[1], req.body.issues[2], req.body.issues[3]);
var obj = JSON.parse(result);
res.send(obj);
});


the second:

getStances: function (a, b, c, d) {
var sendback = '{"stances":[';
sendback += '{"1":[';
var querytext = "SELECT * FROM allIssues WHERE topicname = '"+ a +"'";
query = client.query(querytext,function (callback) {
query.on('row', (row) => {
sendback += "{" + '"'+row['topicstance']+'"' + " : " + '"'+ row['topicdescription'] + '"'+ "} , ";
console.log(sendback);
});
});

querytext = "SELECT * FROM allIssues WHERE topicname = '"+ b +"'";
query = client.query(querytext);
query.on('row', (row) => {
sendback += "{" + '"'+ row['topicstance'] + '"'+ " : " + '"'+ row['topicdescription'] + '"'+ "} , ";
});
query.on('end', () => {
sendback += "]}";
sendback += "]}";
client.end();
return sendback;
});
}


The first function is called by the client app, it then calls
getStances
which makes DB calls and should return a JSON string that has all the db info inside, but instead when
text = getStances()
is called,
text
is set to
undefined
and the rest of router function runs, then it tries to parse
text
to JSON but since its
undefined
, it doesn't work. How do I make the router function asynchronous so that it will wait for
text = getStances()
to complete before it continues with the rest of the code? I have tried callbacks and promises but I get more or less the same results, I am unsure of exactly how they work so maybe I used them incorrectly. Can someone give any examples of how I could fix this?

Answer Source

getStances() needs a way to indicate that it is finished – a callback or promise.

Your function signature could look like:

getStances: function (a, b, c, d, callback) {
     someAsynFunction(arg, function(err, result){
         if (err) return callback(err)   // errors go first by convention
         callback(null, results) // callback(error, result)
    }
}

Then you can use it by passing a function into getStances() for the callback:

let i = req.body.issues // for brevity
text = queries.getStances(i[0], i[1], i[2], i[3], function(err, result){
    if (err) return console.log("error: ", err)
    var obj = JSON.parse(result);
    res.send(obj);
);

This is a basic node pattern.

It's not clear what DB client you are using, but I suspect you have another problem in your code.

It looks like you are making two async calls in getStances() and you are counting on the first one finishing before the second. This is likely to break, so you'll need to find out how your client communicates that it is finished (is there a query.on('finished') or similar?) if you want to insure they happen sequentially.