I'm working with mongojs and I have to retrieve a field from an object taken from mongodb. I can not understand how to return the field:
function retrieveVertById(id){
var result = [];
db.clusters.find({id: id}, function (err, clusters){
if( err || !clusters) console.log("No cluster found");
else clusters.forEach( function (cluster) {
vert = cluster["vertices"];
result.push(vert);
console.log(result);
});
})
return result;
};
var a = retrieveVertById("001");
console.log(a);
The print inside the 'forEach' prints the correct value: (ex. [ [ [ 8, 2, 2 ], [ 2, 2, 5 ], [ 2, 2, 2 ], [ 5, 2, 2 ] ] ] ) On the contrary the print outside the cycle shows an empty array. what does not work with the return? Thanks in advance for your help.
2 Answers 2
I've not used mongojs, but any db lookup will almost certainly be asynchronous. This means the function you passed to db.clusters.find
will not run immediately, but rather when the asynchronous call returns from mongo. Instead of returning a value from retrieveVertById
, try a callback function instead:
function retrieveVertById(id, successCallback) {
db.clusters.find({
id: id
}, function (err, clusters) {
if (err || !clusters) {
console.log("No cluster found");
} else {
var result = [];
clusters.forEach(function (cluster) {
vert = cluster["vertices"];
result.push(vert);
});
successCallback(result);
}
});
};
retrieveVertById("001", function(result) {
console.log(result);
});
5 Comments
retrieveVertById
in the bottom of my example, I'm passing in the callback as an anonymous function. I gave retrieveVertById
a second parameter called successCallback
. So the line successCallback(result);
actually calls the anonymous function: function(result) { console.log(result); }
that I passed in as an argument. Understanding callback functions is a must when writing asynchronous programs.function(result) { console.log(result); }
becomes function(result) { var vert = result; //rest of your code }
. Long answer: do some research on JavaScript callback functions. There's certainly too much to cover in a comment box.oh, i see... you should remember that javascript is async language
return result;
after forEach() will not return result from inside forEach(). you should send result after last value parsed.
var i = 0;
clusters.forEach( function (cluster) {
vert = cluster["vertices"];
result.push(vert);
if (i >= clusters.length)
return result;
i++;
});
1 Comment
return
statement in the forEach body will not 'bubble-up' and act as a return
for the retrieveVertById
function. Second, if the db.cluster.find
method is asynchronous as you said, then you can't return any values from it without the use of a callback function.Explore related questions
See similar questions with these tags.
a
orreturn result, did you make your own
id` or are you mistaken for_id
?find
from a function. You have to use callbacks as yourretrieveVertById
function returns before thefind
callback occurs. Do some searches of existing questions as this is a very common point of confusion.