This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 years ago.
// accept a callback function to execute after getting results...
function searchCoords(callback){
var result = result;
connection.query('SELECT * FROM monitoring', function(err, result){
if(err){
console.log(err);
}
// run the callback function, passing the results...
callback({result: result});
});
}
// call like this...
searchCoords(function(resultsObject){
console.log(resultsObject.result)
});
That's my code, I have an anonymous nested function which returns a variable to the outside by using a callback function. However, the variable returned (result) is an array which i need to use with googlemaps api in node.js. how can i turn this:
searchCoords(function(resultsObject){
console.log(resultsObject.result)
});
into a variable that will contain the whole array so i can call it from themarkers option in the api
Instead of passing a callback to the function why not pass an array you can append to?
function start() {
var myCoords = [];
searchCoords(myCoords);
otherFunction(myCoords); // This function does stuff with myCoords
}
function searchCoords(myCoords){
connection.query('SELECT * FROM monitoring', function(err, result){
if(err){
console.log(err);
}
else {
myCoords.push({result: result});
}
});
}
ok, this would be the code right now:
function searchCoords(myCoords){
var result = result;
connection.query('SELECT * FROM monitoring', function(err, result){
if(err){
console.log(err);
}
myCoords.push({result: result});
});
}
which i call from main.js like this:
function start() {
var myCoords = {};
myCoords = database.searchCoords(myCoords);
console.log(myCoords);
//otherFunction(myCoords); // This function does stuff with myCoords
}
this is close to the solution i'm trying to get, but still doesn't work.. instead, console shows
TypeError: Object #<Object> has no method 'push'
I need a simple function to take the result given by the anonymous nested function and turn it into a variable that i can manipulate more easily, so i can add it to the marker param in google maps api
Related
I have a javascript function "data.getOrdersByUsersModifiedDate" which is making a call to another function "database.getDb". The first function gets a "request" parameter object which has parameters defined. However I can't seem to be getting my head around as to how I can pass that parameter from data.getOrdersByUsersModifiedDate TO database.getDb so that I can use it at line
var orders = db.order.find().toArray(function(err, result)
How can I pass my request parameter from the top function "getOrdersByUsersModifiedDate" to lower function "database.getDb" so I can use it as a filter when I get orders
data.getOrdersByUsersModifiedDate = function (request, next) {
database.getDb(function(err, db) {
if(err) {
next(err);
} else {
var orders = db.order.find().toArray(function(err, result) {
if(err) return next(err);
next(null, result);
});
}
});
};
Use bind.
bind and apply allows a developer to specify the context of the function call (this).
Bind creates a new function with the arguments given to bind (from second parameter), whereas apply calls the function with the new context and the parameters passed as an array (see doc).
This will help you solve scoping hell in callback hell.
The poor man's way to achieve this is using let that=this.
Edit: As pointed by the OP in the comments, arrow functions in ES6 do not bind this ; thus using an arrow function solves the OP issue.
data.getOrdersByUsersModifiedDate = function (request, next) {
database.getDb(function(err, db) {
if(err) {
next(err);
} else {
let {arg1, arg2, arg3} = request; // This should work with ES6
var arg1 = request.arg1; // Otherwise this?
var orders = db.order.find().toArray(function(err, result) {
if(err) return next(err);
next(null, result);
});
}
}.bind(this)); // Scope this to the context of getOrdersByUsersModifiedDate
};
I'm creating an application with SailsJS. I have a question about using callbacks within an Async waterfall and Async each.
I've got two functions inside an async waterfall function. The first callback returns the correct value. The second function has a nested callback. However, the value of the nested callback is stuck within the waterline find function, and never gets returned to the outer function.
Do you know how I could return the value to the outer function?
Thanks for your help.
myFunction: function (req,res) {
async.waterfall([
function(callback){
// native MongoDB search function that returns an Array of Objects
},
function(result, callback){
async.each(resultAll, function (location){
Model.find({location:'56d1653a34de610115d48aea'}).populate('location')
.exec(function(err, item, cb){
console.log (item) // returns the correct value, but the value cant be passed to the outer function
})
})
callback(null, result);
}], function (err, result) {
// result is 'd'
res.send (result)
}
)}
When you use async's function you should you should use you callback once you are done with operations you want to perform.
for example:
async.waterfall([
function(cb1){
model1.find().exec(function(err,rows1){
if(!err){
model2.find({}).exec(function(err,rows2){
var arr=[rows1,rows2];
cb1(null,arr);
});
}else
cb1(err);
})
},function(arr,cb2){
/**
* here in the array....we will find the array of rows1 and rows2 i.e.[rows1,rows2]
* */
model3.find().exec(err,rows3){
if(!err){
arr.push(rows3);
// this arr will now be [rows1,rows2,rows3]
}
else
cb2(err);
}
cb1(null,arr);
}],
function(err,finalArray){
if(err){
// error handling
}
else{
/**
* in finalArray we have [rows1,rows2] ,rows3 is not there in final array
* beacause cb2() was callbacked asynchronously with model3.find().exec() in second function
*/
}
});
so according to me your code should be like
async.waterfall([
function(callback){
// native MongoDB search function that returns an Array of Objects
},
function(result, callback){
async.each(resultAll, function (location){
Model.find({location:'56d1653a34de610115d48aea'}).populate('location')
.exec(function(err, item, cb){
console.log (item) // returns the correct value, but the value cant be passed to the outer function
callback(null, yourData);
/**
* yourData is the data whatever you want to recieve in final callbacks's second parameter
* i.e. callback(null,item) or callback(null,[result,item]) or callback(null,result)
*/
})
})
}], function (err, result) {
// result is 'd'
res.send (result)
}
);
Apply this and you can see things you want in your final callback.
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
I'm using Async to call a function in which it asynchronously calls db and fetches some values then it returns that value to the callback of the async.series. But then how can I pass the value as a return value of the outer function?
Please refer to the comments in the code below for more info.
getUserObjFromDb = function(username, cb) {
var user = {};
async.series([
function(callback){
var userObj = callDb(username);
callback( null, userObj );
}
],
function(err, results){
user = results[0];
cb(user);
});
}
var theUser = getUserObjFromDb(username, function(user){
return user;
}); // theUser is undefined because the outer function getUserObjFromDb did not return anything even though its callback returned, it was only the callback of the async.series which returned.
How can I get the value of user inside passed to theUser ?
I could be doing all this completely wrong and there could be a much simpler approach, so any help would be appreciated.
Thank you.
Honestly, I'm not entirly clear on the question. I'm guessing you are expecting the getUserObjFromDb to return the value that the callback returns.
If so, Try this:
getUserObjFromDb = function(username, cb) {
var user = {};
return async.series([
function(callback){
var userObj = callDb(username);
return callback( null, userObj );
}
],
function(err, results){
user = results[0];
cb(user);
});
}
You are mixing up synchronous and asynchronous models here. The function call getUserObjFromDb is executing right away, and since the async call hasn't completed you can't return it's value from that function.
That is why a callback is necessary. Any code that requires the value for the user needs to be triggered by your callback.
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
I have this recursive function where I need to return some data after the function completes.
// Set Up my Database paramaters
var coachdb = new AWS.DynamoDB({
...
});
// This tracks the array index of the current parameter.
var pos = 0;
function callback(err, data) {
if (err) {
console.log(err, err.stack);
} else if (data.Items.length > 0) {
//return data.Items // Where I need something here to return data
} else if (++pos < params.length) { // Increment the index.
coachdb.query(params[pos], callback); // Recursive call.
}
}
coachdb.query(params[pos], callback); // Kick off the series of calls
Everything inside the function is working just fine. I am querying my database just fine iterating through the possible parameters until the right one is found and then the function ends.
However I am not sure how to pass the data outside the function. Any help would be appreciated.
It's not possible, instead of returning the data you need to write your logic inside the callback.
EDIT: If you don't want to have messy code you need to refactor your code and extract code to separate methods;
function callback(err, data) {
if (err) {
errorLogic(err);
} else if (data.Items.length > 0) {
successLogic(data.Items);
} else if (++pos < params.length) { // Increment the index.
coachdb.query(params[pos], callback); // Recursive call.
}
}
another idea would be the usage of promises to circumvent the need for the callback. Take a look at nano, for example (http://www.mircozeiss.com/async-couchdb-queries-with-nano-and-promises/). In essence, you have an object that will 'at some time' contain the data of your database and at this point in time an event function is called.
pseudocode:
var myPromise = couchdb.insert(...);
myPromise.success(function (mydata){
// here you can fiddle around with your data
})
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
I'm learning Node.js and I'm just starting to work with some MySQL connections. I have a function which is supposed to get a set of rows from the database, which it does correctly. However, I don't know how to return that set of rows afterwards. I tried two options (both explained in comments within the code segment below.
function fetchGameList(){
var ret = 0;
connection.query("SELECT * from tbl", function(err, rows, fields) {
//some stuff happens here, and 'ret' is set to a vlue, for instance
//ret = 7;
//ret has the value 7 here, but if I put 'return ret' here, nothing is returned
});
return ret; //returns 0 because Node is asynchronous and the query hasn't finished yet
}
So, the question is, how do I return the correct value of ret (7 in this case)? Am I even structuring this properly?
You need to pass a callback into your function. Convention is that the callback takes an error (or null if none happened) as the first argument, and results as other arguments.
function fetchGameList(callback) {
var ret;
connection.query("SELECT * from tbl", function(err, rows, fields) {
if (err) {
// You must `return` in this branch to avoid using callback twice.
return callback(err);
}
// Do something with `rows` and `fields` and assign a value to ret.
callback(null, ret);
});
}
You can now do something along the lines of:
function handleResult(err, result) {
if (err) {
// Just an example. You may want to do something with the error.
console.error(err.stack || err.message);
// You should return in this branch, since there is no result to use
// later and that could cause an exception.
return;
}
// All your logic with the result.
}
fetchGameList(handleResult);