How to return Node.js callback - node.js

I have a node.js method that using mongoose in order to return some data, the problem is that since I'm using a callback inside my method nothing is being returned to the client
my code is:
var getApps = function(searchParam){
var appsInCategory = Model.find({ categories: searchParam});
appsInCategory.exec(function (err, apps) {
return apps;
});
}
If I'm trying to do it synchronously by using a json object for example it will work:
var getApps = function(searchParam){
var appsInCategory = JSONOBJECT;
return appsInCategory
}
What can I do?

You can't return from a callback - see this canonical about the fundamental problem. Since you're working with Mongoose you can return a promise for it though:
var getApps = function(searchParam){
var appsInCategory = Model.find({ categories: searchParam});
return appsInCategory.exec().then(function (apps) {
return apps; // can drop the `then` here
});
}
Which would let you do:
getApps().then(function(result){
// handle result here
});

Related

Meteor.js Aysnc is not returning the result keep loading

Here, am calling the method to get the Quickblox result in async method. While i am print the value in console i can get it but the application keep loading not return the result.
Server side:
Meteor.methods({
allquickbloxusers_Methods: function(){
var params = {login: ["99999"]};
var asyncCall = QB1.users.get(params, Meteor.bindEnvironment(function(err, QBuser) {
if(QBuser) {
return QBuser;
} else {
return err;
}
}));
var syncCall = Meteor.wrapAsync(asyncCall);
var res = syncCall();
// now you can return the result to client.
return res;
}
});
To use Meteor.wrapAsync you want to pass it the actual function, not the result of a called function. Like so:
Meteor.methods({
allquickbloxusers_Methods: function(){
var params = {login: ["99999"]};
var syncCall = Meteor.wrapAsync(QB1.users.get)
var res = syncCall(params);
// now you can return the result to client.
return res;
}
});
Basically wrapAsync gives you back a new function that you call with the parameters of the original function.
Knowing this, you can make the function even more concise:
Meteor.methods({
allquickbloxusers_Methods: function(){
var params = {login: ["99999"]};
return Meteor.wrapAsync(QB1.users.get)(params)
}
});

NodeJS + MongoJS: Nested Callbacks Issue

I'm still a n00b with NodeJS so this question may be somewhat elementary.
I'm using MongoJS to read two logically related collections. The first find() returns a value that I pass to the second find() to get the information I need.
I've tried several strategies, the last one (snippet #1) being a class that I export.
Before that I just had a function that did a return, returning the desired value, i.e., "config[0]".
In this code all I did was set the "sapConfig" attribute to the word "test", but when I execute this code the value of "sapConfig" is always "null" after I call the "get_config()" method and - strangest of all - the reference to "this.sapConfig = 'test'" generates an error, i.e., "Cannot set property 'sapConfig' of undefined".
When I had the code just as a simple function with a return statement (snippet #2), no errors were generated but the value returned is always "undefined" although the console.log() statements show that the value of the variable being returned has the desired value. What gives?
Code Snippet #1: Returns Object
"use strict";
var mongojs = require('mongojs'); // MongoDB API wrapper
module.exports = function(regKey) {
this.regKey = regKey;
this.sapConfig = null;
this.get_config = function() {
// Read SAP connection information from our MONGO db
var db = mongojs('mongodb://localhost/MIM', ['Configurations','Registrations']);
db.Registrations.find({ key: this.regKey }, function(err1, registration){
console.log('Reg.find()');
console.log(registration[0]);
db.Configurations.find({ type: registration[0].type }, function(err2, config){
console.log('Config.find()');
console.log('config=' + config[0].user);
this.sapConfig = 'test';
});
});
}
this.get_result = function() {
return this.sapConfig;
}
}
Again, the code in snippet #1, when I make a call to "get_config()", results in an error when it executes the line "this.sapConfig = 'test'".
However, after this error I can execute "obj.get_result()" and I get the value to which it was initialized, i.e., null. In other words, that same code doesn't generate an error saying that the "this" is undefined as .in the "get_config()" method
Code Snippet #2: Using the "return" statement
"use strict";
var mongojs = require('mongojs'); // MongoDB API wrapper
module.exports = function(regKey) {
// Read SAP connection information from our MONGO db
var db = mongojs('mongodb://localhost/MIM', ['Configurations','Registrations']);
db.Registrations.find({ key: regKey }, function(err1, registration){
console.log('Reg.find()');
console.log(registration[0]);
db.Configurations.find({ type: registration[0].type }, function(err2, config){
console.log('Config.find()');
console.log('config=' + config[0].user);
return config[0].user;
});
});
}
When I receive the return value and inspect it, it's "undefined". For example, at the Node CL I issue the following commands:
var config = require('./config') // The name of the module above
> var k = config('2eac44bc-232d-4667-bd24-18e71879f18c')
undefined <-- this is from MongoJS; it's fine
> Reg.find() <-- debug statement in my function
{ _id: 589e2bf64b0e89f233da8fbb,
key: '2eac44bc-232d-4667-bd24-18e71879f18c',
type: 'TEST' }
Config.find()
config=MST0025
> k <-- this should have the value of "config[0]"
undefined
You can see that the queries were successful but the value of "k" is "undefined". What's going on here?
I don't care which approach I use I just need one of them to work.
Thanks in advance!
this.sapConfig is not accessible. Thats because this refers to within the current function. What I like todo, is have a variable that refers to the function instance that you know sapConfig is located in.
Ex:
function Foo() {
var self = this;
this.test = "I am test";
var bar = function(){
return function(){
console.log(this.test); //outputs undefined (because this refers to the current function scope)
console.log(self.test); //outputs "I am test";
}
}
}
Here is your first code snippit with my example implemented:
"use strict";
var mongojs = require('mongojs'); // MongoDB API wrapper
module.exports = function(regKey) {
var self = this;
this.regKey = regKey;
this.sapConfig = null;
this.get_config = function() {
// Read SAP connection information from our MONGO db
var db = mongojs('mongodb://localhost/MIM', ['Configurations', 'Registrations']);
db.Registrations.find({ key: this.regKey }, function(err1, registration) {
console.log('Reg.find()');
console.log(registration[0]);
db.Configurations.find({ type: registration[0].type }, function(err2, config) {
console.log('Config.find()');
console.log('config=' + config[0].user);
self.sapConfig = 'test';
});
});
}
this.get_result = function() {
return self.sapConfig;
}
}
For your second snippet. You are trying to return a value from within your nested callback. Since nested functions are asyncronous, you cannot do that.
Here is how I like to return values from nested callbacks:
Ex2:
//Function example
var functionWithNested = function(done) {
//Notice the done param.
// It is going to be a function that takes the finished data once all our nested functions are done.
function() {
//Do things
function() {
//do more things
done("resultHere"); //finished. pass back the result.
}();//end of 2nd nested function
}(); //end of 1st nested function
};
//Calling the function
functionWithNested(function(result) {
//Callback
console.log(result); //resultHere
})
Here is your code using that example:
"use strict";
var mongojs = require('mongojs'); // MongoDB API wrapper
module.exports = function(regKey, done) {
// Read SAP connection information from our MONGO db
var db = mongojs('mongodb://localhost/MIM', ['Configurations', 'Registrations']);
db.Registrations.find({ key: regKey }, function(err1, registration) {
console.log('Reg.find()');
console.log(registration[0]);
db.Configurations.find({ type: registration[0].type }, function(err2, config) {
console.log('Config.find()');
console.log('config=' + config[0].user);
done(config[0].user);
});
});
}
//Then wherever you call the above function use this format
// if config is the name of the function export above...
new Config().(regKey, function(result){
console.log(result); //config[0].user value
})
Lots and lots of code, but I hope you were able to follow it. Let me know if you have any more questions! Cheers.

Use generator function with yield inside a class in ES2015 using KoaJS

I’m trying to call a generator function inside a class from the constructor, it runs but nothing happens (my console.log are not printing) as if the generator function is never called.
Update #1:
Here's an updated version of my code. I am able to access my findOne function with the next() function, but since I wrapped "users" with co-monk, I tough there was no need to call it. I'm still not sure why I need to call next(0) function 2 times to jump over the yield call.
Therefore, I'm now getting undefined when I print the output of "userData".
If my issue is related to understand on how yield works, maybe pointing me to direction could help me. I tried using generator functions with yield calls apart from a class and it worked perfectly fine with monk/co-monk.
Update #2:
I should also mention that I'm using babel6 for transcript.
"use strict";
var monk = require("monk");
var wrap = require("co-monk");
var db = monk("localhost/test");
var users = wrap(db.get("users"));
class User {
constructor(user) {
if (typeof user == "object") {
var findUser = this.findOne(user.id);
findUser.next();
findUser.next();
if(findUser != null){
this._user = user;
}
}
else {
console.error("user parameter is not an oject");
return false;
}
}
*findOne(id) {
var userData = yield users.findOne({_id: id});
console.log(userData); // Getting undefined
this._user = userData;
};
}
var _user = new User({id : "1234"});
console.log(_user);
export default User;
It looks like the docs for co-monk are a bit vague, but looking at the one test it has, it needs to be used within co.
var co = require("co");
// rest of your code
findOne(id) {
return co(function* () {
var userData = yield users.findOne({_id: id});
console.log(userData); // Getting undefined
this._user = userData;
});
};
What it won't allow you to do is seamlessly transition async code back into sync code, so this.findOne() will return a promise. As a result, your User object may not be populated immediately after called new User({id : "1234"}).
tried with the lib co and it worked.
It looks like co-monk is broken inside a generator function inside a class at this moment.
so here's what worked for me :
"use strict";
var monk = require("monk");
//var wrap = require("co-monk");
var db = monk("localhost/test");
var users = (db.get("users"));
var co = require('co');
class User {
constructor(user) {
if (typeof user == "object") {
var findUser = this.findOne(user.id);
this._user = user;
}
else {
console.error("The user params is not an object");
}
}
findOne(id) {
co(function* () {
return yield users.findOne({_id: id});
}).then(function (val) {
console.log(val);
}, function (err) {
console.error(err.stack);
});
};
}

How to execute complicated Parse or Express promise pattern

I have code of the following pattern in express using Parse Queries:
var function1 = function(a){
if(a){
var setSomething = new Parse.Object
setSomething.set("thing", "stuff");
setSomething.save();
}else{
var query = new Parse.Query(Shortcut);
query.first({
success: function(getThing){
getThing.set("thing", "otherStuff");
getThing.save();
}
})
}
}
var function2 = function(){
var a = true;
function1(a)
}()
var function3 = function(){
var a = false;
function1(a)
}()
I'd like to use promises to do all of the saves at once and then res.send back to my front end but I can't figure out the pattern and whether I should be using Parse promises or some other promise library and if I am using Parse promises if it is Parse.Promise() or Parse.Promise.as() and either way if I'm pushing to arrays or calling the 'when' method and then where I should be calling the when method.
I can't believe this works but it look like it does!
I based my answer off this post:
Parse Cloud Code: How to Invoke Promises for Async Saving
var function1 = function(a){
if(a){
var setSomething = new Parse.Object
setSomething.set("thing", "stuff");
return setSomething.save();
}else{
var query = new Parse.Query(Shortcut);
query.first({
success: function(getThing){
getThing.set("thing", "otherStuff");
return getThing.save();
}
})
}
}
var function2 = function(){
var a = true;
return function1(a)
}()
var function3 = function(){
var a = false;
return function1(a)
}()
Parse.Promise.when(function2(), function3())
.then(function(){
res.send("Success")})
Key point to notice for the newbie: I return all of the inner functions and the save functions in function1 also.

Return counter in db.collection.count()'s callback doesn't work, why?

I want to track the number of documents I have within a collection in a node.js server
using mongodb driver. I can insert, delete and update propperly but when I try to count, it works until I try to store that value, moment in which it returns nothing.
Here is my code:
var db_collection = db.collection('collection');
var countCollections = function () {
var response_count_collections = null;
db_mensajes.count(function(err,number_of_collections){
if (err){
console.log(err);
} else {
response_of_collections = number_of_collections;
console.log('Number of collections: '+number_of_collections);
}
});
return response_count_collections;
};
It logs the number_of_collections correctly but it doesn't return me the right value. In my example it returns null (how I defined my var response_count_collections;) and if I
try to return number_of_collections; within the db_collections.count()'s callback like this:
var db_collection = db.collection('collection');
var countCollections = function () {
var response_count_collections = null;
db_mensajes.count(function(err,number_of_collections){
if (err){
console.log(err);
} else {
console.log('Number of collections: '+number_of_collections);
return number_of_collections;
}
});
};
It returns me "undefined". Is there any way to achieve what I want?
Its because it returns the variable before the function is completely executed.
If you want it to be asynchronous then you will have to learn to control the flow of the program using some node modules like async.
Update:
Have a look at this question, it shows how to return value from an async function using callback correctly.

Resources