I have started learning promises and I wanted use it with mongoose. I have read that mongoose promises are primitive so I have applied to q by using this code:
var mongoose = require('mongoose');
var q = require('q');
mongoose.Promise = q.Promise;
The I have created my schema and model and try to call functions via promises:
User.findOne({chat_id: 2}).exec().then(
function (obj) {
console.log("SUCCESS");
console.log(obj);
},
function (err) {
console.log("ERROR");
console.log(err);
}
).done();
When I call this code it always calls resolve part and skips reject part. My console shows always function which has SUCCESS line even if I intentionally query for not existing data.
Am I missing something, or mongoose will always use Model.method().exec().then(resolveFunction)?
Not finding something is not an error, it just means you did not find something. See: What is returned from Mongoose query that finds no matches? and likely your problem is related to this Mongoose JS findOne always returns null
Also try this: Note I have not worked with q.Promise, I use bluebird.
User.findOne({chat_id: 2}).exec().then(
function (obj) {
if (obj.chart_id === 2) {
console.log("SUCCESS");
console.log(obj);
} else {
console.log("obj with obj.chart_id == 2 NOT FOUND");
console.log(obj);
}
},
function (err) {
console.log("ERROR");
console.log(err);
}
).done();
Related
I'm trying to make multiple database queries using bluebird's Promise.each(). The part where I'm stuck is that I'm not able to handle all the rejections (if multiple promises fail). If I do the same thing using Promise.all() it works fine(It will! because in Promise.all() if 1 promise fails the result is rejected too). My question is:
How should I handle rejections in Promise.each()?
function foo(bar){
return new Promise(resolve, reject){
var query = "elect count(*) from students Where 1=1";//DELIBRATE MISTAKE
connection.query(query, function(err, result){
if(err){reject(err)}resolve(result);
})
}
}
function api(req, res){
var tasks = [];
for(var i = 0; i < 10; i++){
tasks.push(foo(bar));
}
Promise.each(tasks).catch(err=>{return err;});
res.send('message')
}
Response:
Unhandled rejection Error: ER_PARSE_ERROR
You're using Bluebird#each method incorrectly. This method do the following:
Iterate over an array, or a promise of an array, which contains promises (or a mix of promises and values) with the given iterator function with the signature (value, index, length) where value is the resolved value of a respective promise in the input array.
So the first parameter must be an array of promises/values, and the second is a callback which accepts three parameters: value, index, length.
Working example:
let queryAsync = Promise.promisify(connection.query, { context: connection });
function foo(bar) {
var query = 'elect count(*) from students Where 1=1'; // DELIBRATE MISTAKE
return queryAsync(query);
}
function api(req, res){
var tasks = [/* TODO: fill array with taskIds or something else*/];
Promise
.each(tasks, task => foo(task))
.then(() => res.send('message'))
.catch(err => {
console.log(err);
res.status(500).send(err);
});
}
In the example above I use Bluebird#promisify method to promisify callback-style connection.query function. Bluebird already presents the promisification functionality, you shouldn't create your own.
I have two files in my application,
DesignFactory.js:
var fs = require('fs');
var dotenv = require('dotenv');
dotenv.load();
var designtokenfile = require ('./designtokenfile');
var designtokendb = require ('./designtokendb');
var TYPE=process.env.TYPE;
var DesignFactory={};
DesignFactory.storeDesign = function(TYPE) {
if (TYPE == 'file') {
var data=design.designtokenfile.load();
console.log(data);
} else if (TYPE == 'db') {
return designtokendb;
}
};
module.exports.design=DesignFactory;
now, I have another designtokenfile.js file,
designtokenfile.js:
var fs = require('fs');
var load = function() {
fs.readFile('output.txt', 'utf8', function (err,data) {
return data;
if (err) {
return console.log(err);
}
});
};
module.exports.load=load;
So my problem is am not able get data returned from load method. when I print data inside storeDesign method returned from load function, it displays undefined.
but I want contents of output.txt inside storeDesign method.
Please help me.
Instead of:
var load = function() {
fs.readFile('output.txt', 'utf8', function (err, data) {
return data;
if (err) {
return console.log(err);
}
});
};
which has no way of working because the if after the return would never be reached, use this:
var load = function(cb) {
fs.readFile('output.txt', 'utf8', function (err,data) {
if (err) {
console.log(err);
return cb(err);
}
cb(null, data);
});
};
and use it like this:
load((err, data) => {
if (err) {
// handle error
} else {
// handle success
}
});
Or use this:
var load = function(cb) {
return new Promise(resolve, reject) {
fs.readFile('output.txt', 'utf8', function (err, data) {
if (err) {
console.log(err);
reject(err);
}
resolve(data);
});
});
};
and use it like this:
load().then(data => {
// handle success
}).catch(err => {
// handle error
});
In other words, you cannot return a value from a callback to asynchronous function. Your function either needs to tak a callback or return a promise.
You need to reed more about asynchronous nature of Node, about promises and callbacks. There are a lot of questions and answers on Stack Overflow that I can recommend:
promise call separate from promise-resolution
Q Promise delay
Return Promise result instead of Promise
Exporting module from promise result
What is wrong with promise resolving?
Return value in function from a promise block
How can i return status inside the promise?
Should I refrain from handling Promise rejection asynchronously?
Is the deferred/promise concept in JavaScript a new one or is it a traditional part of functional programming?
How can I chain these functions together with promises?
Promise.all in JavaScript: How to get resolve value for all promises?
Why Promise.all is undefined
function will return null from javascript post/get
Use cancel() inside a then-chain created by promisifyAll
Why is it possible to pass in a non-function parameter to Promise.then() without causing an error?
Implement promises pattern
Promises and performance
Trouble scraping two URLs with promises
http.request not returning data even after specifying return on the 'end' event
async.each not iterating when using promises
jQuery jqXHR - cancel chained calls, trigger error chain
Correct way of handling promisses and server response
Return a value from a function call before completing all operations within the function itself?
Resolving a setTimeout inside API endpoint
Async wait for a function
JavaScript function that returns AJAX call data
try/catch blocks with async/await
jQuery Deferred not calling the resolve/done callbacks in order
Returning data from ajax results in strange object
javascript - Why is there a spec for sync and async modules?
Return data after ajax call success
fs.readFile ist asynchrone so you need to pass a callback function or use fs.readFileSync
You are getting undefined because of asynchronous nature.. Try for the following code:
var fs = require('fs');
var load = function(callback) {
fs.readFile('output.txt', 'utf8', function (err,data) {
//return data;
callback(null, data);
if (err) {
callback("error", null);
}
});
};
module.exports.load=load;
var fs = require('fs');
var dotenv = require('dotenv');
dotenv.load();
var designtokenfile = require ('./designtokenfile');
var designtokendb = require ('./designtokendb');
var TYPE=process.env.TYPE;
var DesignFactory={};
DesignFactory.storeDesign = function(TYPE) {
if (TYPE == 'file') {
var data=design.designtokenfile.load(function(err, res){
if(err){
} else {
console.log(data);
}
});
} else if (TYPE == 'db') {
return designtokendb;
}
};
module.exports.design=DesignFactory;
Here's my original code to fetch a user php session which is stored in redis:
var session_obj;
var key = socket.request.headers.cookie.session
session.get('PHPREDIS_SESSION:'+key,function(err,data){
if( err )
{
return console.error(err);
}
if ( !data === false)
{
session_obj = PHPUnserialize.unserializeSession(data);
}
/* ... other functions ... */
})
I would like to rewrite the code with Promise, but I can't get the data returned:
Promise.resolve(session.get('PHPREDIS_SESSION:'+key)).then(function(data){
return data;
}).then(function(session){
console.log(session); // this returns true, but not the session data
session_obj = PHPUnserialize.unserializeSession(session);
}).catch(function(err){
console.log(err);
})
The session returned just boolean true instead of the session data. The original redis get function has two arguments. I assumed the promise just returned the first argument which was err in the original. So I tried
Promise.resolve(session.get('PHPREDIS_SESSION:'+key)).then(function(err,data){
console.log(data) // return undefined
})
but it wasn't working either.
Does anyone know if redis could work with Promise?
You were trying to use Promise.resolve wrong, it expects a Promise and session.get by default doesn't return a Promise. You first need to promisify it. (or promisifyAll)
session.getAsync = Promise.promisify(session.get);
// OR
Promise.promisifyAll(session); //=> `session.getAsync` automatically created
// OR
Promise.promisifyAll(redis); //=> Recursively promisify all functions on entire redis
Then use the new function which returns the promise like you would use a promise, you don't even need to wrap it with Promise.resolve, just this:
session.get('PHPREDIS_SESSION:' + key).
then(function(data) {
// do something with data
}).
catch(function(err) {
// handle error with err
});
I have a function getStuff() that needs to return the results of a query against MongoDB. I'm using nodejs and the mongod module. Here's the code I've got.
var mongo = require("mongod");
var url = "mongodb://localhost:27017/my-mongo";
function getStuff() {
var db = new mongo(url, ["stuff"]);
var promise = db.stuff.find()
.then(function (result) {
console.log(result);
return result;
}).done(function (data) {
console.log(data);
return data;
});
console.log(promise);
return promise;
}
exports.getStuff = getStuff;
I'm obviously missing something about how promises work. I'm getting good data in the first two console.log() calls. However the getStuff() function always returns undefined. This seems like it should be a super simple use case but I'm banging my head on my desk trying to get it to work properly. Any help would be greatly appreciated.
Your last log and return statement run as your .find.then.done chain are still being executed (that's Async for ya!). That's why promise is still undefined.
Try returning the entire promise, like instead of
var promise = db.stuff.find()...
try
return db.stuff.find()...
...that needs to return the results...
to get the data from getStuff
function getStuff(callback) {
var db = new mongo(url, ["stuff"]);
db.stuff.find()
.done(function (result) {
console.log(result);
callback(result);
}));
}
then you can call it like this
getStuff(function(data){
//here you will get your results
});
I'm trying to run a function when two compilation steps are complete, but the success callback keeps getting called even one fails. Here's the code:
function compile(tplStr) {
return new Promise(function(resolve,reject) {
// compile template here
var tpl = new function(){};
resolve(tpl);
});
}
function parse(json) {
return new Promise(function(resolve,reject) {
try {
var obj = JSON.parse(json);
resolve(obj);
} catch(err) {
console.log('JSON parse failed');
reject(err);
}
});
}
var i = 0;
function bothReady() {
$('#c').text(++i);
}
function oneFailed(err) {
console.log('oneFailed hit');
$('#c').text(err.message);
}
var compileProm = compile($('#a').val());
var parseProm = parse($('#b').val());
Promise.all([compileProm,parseProm]).then(bothReady).catch(oneFailed);
$('#a').on('input', function() {
Promise.all([compile($('#a').val()),parseProm]).then(bothReady).catch(oneFailed);
});
$('#b').on('input', function() {
Promise.all(compileProm,parse($('#b').val())).then(bothReady).catch(oneFailed);
});
code pen
When I create a syntax error in the JSON portion it logs "JSON parse failed" but does not log "oneFailed hit" like I'd expect. Why not? Shouldn't the .catch block be ran if any of the promises are rejected?
Your code doesn't work correctly when something is typed inside of #b because instead of passing an iterable to Promise.All 2 parameters are passed instead.
The result is that while both promises run, only the result of the first one is taken into account by the continuation of all.
The code read
Promise.all(compileProm,parse($('#b').val())).then(bothReady).catch(oneFailed);
Instead of
Promise.all([compileProm,parse($('#b').val())]).then(bothReady).catch(oneFailed);
PS: The 2 other calls are correct it explain why the problem seem to happen only when editing the JSON.