How to execute complicated Parse or Express promise pattern - node.js

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.

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)
}
});

promise flow - bluebird

I'm trying to use ffmpeg to cut a few seconds of a directory with mp3s.
But my actual problems comes with using promises.
Instead of starting one ffmpeg process after the other it starts up one for each file immediately.
My guess is the promise isn't waiting for the resolve and I didn't understand it properly.
var P = require('bluebird');
var fs = P.promisifyAll(require("fs"));
function transcode(filename) {
return P.delay(1000).then(function() {
console.log(filename);
});
}
var in_dir = "./somedir/";
var getFiles = function(){
return fs.readdirAsync(in_dir);
};
getFiles().mapSeries(function(filename){
transcode(filename);
});
I've created a simplified version of your code. The only missing thing was the return statement for the final closure:
var P = require('bluebird');
var fs = P.promisifyAll(require("fs"));
function transcode(filename) {
return P.delay(1000).then(function() {
console.log(filename);
});
}
var in_dir = "./somedir/";
var getFiles = function(){
return fs.readdirAsync(in_dir);
};
getFiles().mapSeries(function(filename){
return transcode(filename);
});

Send parameters between promises

Im doing a asynchronous process with node.js. using promises. My code is like this:
var net = require('net');
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database('MyBBDD.db');
var net = require('net');
var Q = require("q");
var firstFunction = function(v_user, v_mystring){
var deferred = Q.defer();
var mi;
stmt = db.prepare("SELECT text1 FROM my_table WHERE user = ?");
stmt.bind (v_user);
stmt.get(function(error,row){
if(!error && row){
deferred.resolve({string: v_mystring, query: row.text1});
}
deferred.reject(new Error(error));
});
return deferred.promise;
};
var secondFunction = function(result){
console.log(result.string);
console.log(result.query);
};
firstFunction('user000','Hello').then(secondFunction);
All in my code work fine but now, I want to concatenate in secondFunction my string received from firstFunction with other string for example "MyNewString".
Somebody know how can I solve it? Can I send "MyNewString" from my firstFunction to my secondFunction?
Thanks in advance.
Best regards.
The best to solve it will be resolve promise with object. Instead of returning just one value - result of querying DB you can return object that covers needed value.
With bind:
function firstFunction(string) {
return Promise.resolve({string: string, query: 'some result of query'})
}
function secondFunction(otherText, result) {
console.log(result.query) // you have still access to result of query
return result.string + otherText
};
firstFunction('foo').then(secondFunction.bind(null, 'bar')).then(console.log);
With closure
function firstFunction(string) {
return Promise.resolve({string: string, query: 'some result of query'})
}
function secondFunction(text) {
return function(result) {
return result.string + text
}
};
firstFunction('foo').then(secondFunction('bar')).then(console.log);
With anonymous function expression
function firstFunction(string) {
return Promise.resolve({string: string, query: 'some result'})
}
function secondFunction(text, otherText) {
return text.string + otherText
};
firstFunction('foo').then(function(result) {
return secondFunction(result, 'bar')
}).then(console.log);

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 return Node.js callback

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
});

Resources