var request = require('superagent-q');
createWordFrequency(name, freq) {
return request.post(this.hostname + "/api/frequency/" + name)
.send({'freq': freq}).end()
.then(function(res) {
if (!res.ok) throw new Error(res.status);
console.log("success:"+JSON.stringify(res.body));
return res.body.word;
});
}
The post call is never made and there is no effect. A breakpoint inside then() does not trigger and the request is never made. I cannot step into the post() call in the debugger.
Also tried:
createWordFrequency(name, freq) {
return request.post(this.hostname + "/api/frequency/" + name)
.send({'freq': freq})
.end(function(err, res) {
if (err) throw new Error(err);
console.log("success:"+JSON.stringify(res.body));
return res.body.word;
});
}
Related
I am using expressJs, This is the query which I am executing it multiple time
router.post('/Index_api/Reminder/Delete',function(req, res)
{
Reminder_Id = req.body;
DeleteRow('Reminders','Reminder_Id',Reminder_Id.Reminder_Id);
});
int this is the DeleteRow Function
function DeleteRow(TableName,WCC, id)
{
var query ="Delete FROM `"+TableName + "` WHERE `"+ WCC +"` =" + id;
conn.query(query,function(err,result)
{
if(err)
{
console.error(err);
return;
}else{
console.log(result);
}
});
}
I am posting data to this route like this:
function DeleteRow(id)
{
$.post('/Index_api/Reminder/Delete',{
Reminder_Id:id
});
$("#row"+id).remove();
}
if I want to delete 6 records together there is no problem but by the 7th one is not executed and gets stuck.
I am also using nodemon and reload package.
Your router.post() route handler is not returning any response. Thus, the browser is still waiting for some sort of response. The browser has a maximum number of connections it will make to any given host so once you have too many connections all sitting there waiting for a response, then the browser queues the next requests until one of the prior ones finishes.
Eventually those requests will time out, but that can take a long time.
To fix, just send a response from your route handler:
router.post('/Index_api/Reminder/Delete',function(req, res) {
Reminder_Id = req.body;
DeleteRow('Reminders','Reminder_Id',Reminder_Id.Reminder_Id);
res.send("ok");
});
Or, if you want the post to actually respond after DeleteRow() is done, you can let DeleteRow() send the right response by passing res to it and letting it send the response.
router.post('/Index_api/Reminder/Delete',function(req, res) {
Reminder_Id = req.body;
DeleteRow('Reminders','Reminder_Id',Reminder_Id.Reminder_Id, res);
});
function DeleteRow(TableName, WCC, id, res) {
var query = "Delete FROM `" + TableName + "` WHERE `" + WCC + "` =" + id;
conn.query(query, function(err, result) {
if (err) {
console.error(err);
res.status(500).send("delete failed");
} else {
res.send("delete OK");
}
});
}
Then, you should probably also change your client code to actually look at the returned status and act accordingly.
function DeleteRow(id) {
$.post('/Index_api/Reminder/Delete',{
Reminder_Id:id
}).then(function(result) {
if (result.status == 200) {
// successful
$("#row"+id).remove();
} else {
// handle server error here
}
}, function(err) {
// network error here
});
}
I am trying to use Promises instead of Callback in my Lambda Function in NodeJs 4.3. What I'm trying to do is read a config file from S3 and use the configuration to connect to a DB and execute a SELECT statement on a table. When I test the function, I don't get any errors in the console.
I have defined my function as follows:
function setUpConnection(response) {
console.log("S3 Response " + JSON.stringify(response));
return new Promise(function(resolve, reject) {
config = response.Body.toString('utf-8');
config = JSON.parse( config );
// set up connection from S3 config file
var con = mysql.createConnection({
host: config.hostaddress,
user: config.user,
password: config.pass,
database: config.dbname
});
console.log("connection " + JSON.stringify(con));
console.log("config " + JSON.stringify(config));
// create connection
con.connect(function(err){
if(err){
// Output connection details for debugging
console.log('Error connecting to DB');
return Promise.reject(new Error(output));
}
});
// Run Select Query
con.query("SELECT * FROM goodsreceiptheader WHERE invoiceKey = ?", [invoicekey], function(err,res){
if(err){
console.log(err);
con.end();
return Promise.reject(new Error(output));
}
if ( res.length <= 0 ){
console.log('Response Object ' + JSON.stringify(res));
con.end();
return Promise.reject(new Error(output));
}
resolve(res);
})
})
}
The function is being called by this function:
// Setup goodsreceipt info
var goodsreceipt = data.goodsreceipt;
getObjectPromise = s3bucket.getObject(params).promise()
getObjectPromise
.then(setUpConnection)
.then(validateRecord)
.catch(callback(null, Error))
When I execute this code, I am only seeing the result of the code
console.log("S3 Response " + JSON.stringify(response));
on the second line. Is there a problem with the way I configured setUpConnection?
You're using rejection in a wrong way.
return Promise.reject(new Error(output));
Should be replaced with
reject(new Error(output));
return;
Also catch call looks strange: it calls callback immediately. Usually catch block looks like that:
somePromise.catch((error) => {
console.error(error); // If output required.
callback(error); // If callback provided.
});
Move con.query call inside of con.connect callback.
First of all, from where output is coming? I don't see it anywhere defined.
Second of all it is considered as good practice to always throw/reject with an instance of Error, in your example i guess, at least by variable name, output is not an instance of Error. Third thing in general only valid use case in my opinion of using new Promise constructor is when you want to transform callback api to promise which you are doing here (which is good) or you when deal with setTimeout/setInterval
Anyway you are using Promise.reject where you have reject in scope already which is not how you should reject your promise in this case. Next thing is that you are using con.query outside of callback that is provided to con.connect which effectively means you are calling query before connection was successfully established, try with something like:
return new Promise(function(resolve, reject) {
...
con.connect(function(err){
if(err){
return reject(new Error('...'));
}
// Run Select Query
con.query(..., ..., function (err,res) {
if(err){
...
return reject(new Error('...'));
}
if (res.length <= 0 ){
...
return reject(new Error(output));
}
return resolve(res);
})
});
})
Few sides notes:
1. Check does this lib have promise api, probably it should in that way you dont need to promisify things around on your own.
2. If it doesnt have you can always use libs like bluebird to promisfy code for you
You rejection of promise is wrong
Try in this way
function setUpConnection(response) {
console.log("S3 Response " + JSON.stringify(response));
return new Promise(function(resolve, reject) {
config = response.Body.toString('utf-8');
config = JSON.parse( config );
// set up connection from S3 config file
var con = mysql.createConnection({
host: config.hostaddress,
user: config.user,
password: config.pass,
database: config.dbname
});
console.log("connection " + JSON.stringify(con));
console.log("config " + JSON.stringify(config));
// create connection
con.connect(function(err){
if(err){
// Output connection details for debugging
console.log('Error connecting to DB');
return reject(err);
}
});
// Run Select Query
con.query("SELECT * FROM goodsreceiptheader WHERE invoiceKey = ?", [invoicekey], function(err,res){
if(err){
console.log(err);
con.end();
return reject(err);
}
if ( res.length <= 0 ){
console.log('Response Object ' + JSON.stringify(res));
con.end();
return reject('response less 0');
}
resolve(res);
})
})
}
I'm new to NodeJs and code I'm working with is using Q framework for promises.
And it seems that I don't understand the 'Q' framework too well, I'm running into a case when promises are returning too early.
Here is my code:
BridgeInfo.getBridgeInfo(exten)
.then(function processBridgeInfo(bridge_info) {
console.log("Nitesh -- bridge info is back, yay");
if (bridge_info !== undefined) {
conf_bridge = new VoxConfBridge(ari);
conf_bridge.init(bridge_info);
/**Add the bridge to the bridgeList**/
bridgeList[conf_bridge.bridge.id] = conf_bridge;
console.log("Bridge ID to register is "+ conf_bridge.bridge.id);
self.registerEvents(conf_bridge.bridge);
conf_bridge.registerUser(event, false, channel);
} else {
console.log("Unknown extension [" + exten + "] blocking it");
ChannelDriver.blockChannel(ari, channel.id);
}
})
.catch(function handleError(err) {
console.error("Nitesh -- [voxbridgemanager] error occured "+err);
});
The above code calls a function getBridgeInfo, this function is supposed to do some DB queries and return the result.
Here is the code in getBridgeInfo
BridgeInfo.getBridgeInfo = Q.async(function(bridge_identifier) {
console.log("Nitesh -- Getting the bridge info for ["+ bridge_identifier + "]");
if (bridge_identifier !== undefined) {
db.getConfBridgeProfile(bridge_identifier)
.then(function processBridgeProfile(result) {
if (result !== undefined) {
console.log("Nitesh -- Bridge Info is "+ JSON.stringify(result));
var bridge_info = new BridgeInfo();
bridge_info.init(result)
.then (function bridgeInfoInitDone() {
return bridge_info;
})
.catch( function handleError(err) {
console.error("Nitesh ---[bridgeInfoInit] Error is "+ err);
});
}
else {
console.log("Can't find any bridge profile for this identifier ["+ bridge_identifier + "]");
}
}, function handleError(err) {
console.error("Failed to retrieve bridgeInfo");
});
} else {
console.error("Received an invalid identifier");
}
});
**When I run this code, I see that in my main code,which calls getBrigeInfo, it hits its catch error handler even before getBRidgeInfo has executed completely, getBridgeInfo's SQL query results appear afterwards.
I think the way I'm using promises isn't being done correctly, any explanations please
Your missing the key part of what promises can do.
You should not need to do any catch statements in your getBridgeInfo. You should return the whole promise that gets the SQL data... and handle it in your first block of code BridgeInfo.getBridgeInfo(exten)
Assuming that db.getConfBridgeProfile(bridge_identifier); returns a promise
Example:
BridgeInfo.getBridgeInfo = function(bridge_identifier) {
console.log("Nitesh -- Getting the bridge info for ["+ bridge_identifier + "]");
if (bridge_identifier !== undefined) {
return Q.fcall(function () {
throw new Error("Received an invalid identifier");
});
}
return db.getConfBridgeProfile(bridge_identifier);
}
I've also seperated out your process query... keep things simple.
BridgeInfo.processBridgeProfile = function(result) {
if (result !== undefined) {
console.log("Nitesh -- Bridge Info is "+ JSON.stringify(result));
var bridge_info = new BridgeInfo();
return bridge_info.init(result);
}else{
return Q.fcall(function () {
throw new Error("Can't find any bridge profile for this identifier ["+ bridge_identifier + "]");
});
}
Return promises and handle the catch in the main function. Your getting stuck in handling a catch, the SQL results are not getting returned like they should.
Call:
BridgeInfo.getBridgeInfo(bridge_identifier).then(function(result){
return BridgeInfo.processBridgeProfile(result)
}).then(function(){
//Do the rest here
}).catch(function(){
//One catch to rule them all :)
});
Im trying to implement some way to stop my code to redirect me before I get the response from the omdb api I am using.
My function for making a search for a movie and saving all titles in a session looks like this:
app.post('/search', isLoggedIn, function(req, res) {
function getMovies(arg, callback){
console.log('In getMovies');
console.log('searching for '+arg);
omdb.search(arg, function(err, movies) {
if(err) {
return console.error(err);
}
if(movies.length < 1) {
return console.log('No movies were found!');
}
var titles = [];
movies.forEach(function(movie) {
// If title exists in array, dont push.
if(titles.indexOf(movie.title) > -1){
console.log('skipped duplicate title of '+movie.title);
}
else{
titles.push(movie.title);
console.log('pushed '+movie.title);
}
});
// Saves the titles in a session
req.session.titles = titles;
console.log(req.session.titles);
});
// Done with the API request
callback();
}
var title = req.body.title;
getMovies(title, function() {
console.log('Done with API request, redirecting to GET SEARCH');
res.redirect('/search');
});
});
However I dont know if I implement callback in the right way, because I think there can be a problem with the api request actually executing before the callback, but not finishing before. And therefor the callback is working..
So I just want 2 things from this question. Does my callback work? And what can I do if a callback won't solve this problem?
Thankful for all answers in the right direction.
Add
callback();
To, like this
omdb.search(arg, function(err, movies) {
if (err) {
return console.error(err);
}
if (movies.length < 1) {
return console.log('No movies were found!');
}
var titles = [];
movies.forEach(function(movie) {
// If title exists in array, dont push.
if (titles.indexOf(movie.title) > -1) {
console.log('skipped duplicate title of ' + movie.title);
} else {
titles.push(movie.title);
console.log('pushed ' + movie.title);
}
});
// Saves the titles in a session
req.session.titles = titles;
callback();
});
omdb.search is asynchronous function that's why callback executed before omdb.search
I am implementing a restify middleware for session authentication. The function contains nested asynchronous db calls: db.sessions.remove() within the callback of db.sessions.findOne().
The 'return' statements are confusing me because I'm not sure if I am returning next() or next(err) from the callback back to verifyUserSession(), or is it just returning from verifyUserSessions? Am I doing this right?
function verifyUserSession(req, res, next) {
if (req.headers.sessionKey)
{
db.sessions.findOne(req.headers.sessionKey, function(err, session) {
if (err)
{
return next(err);
}
if (!session)
{
return next(new Error({'message': 'Session does not exist'}));
}
if ((new Date().getTime() - session.timestamp.getTime())/86400000 > 60)
{
db.sessions.remove({sessionKey: req.headers.sessionKey}, function(err){
if (err)
{
return next(err);
}
return next(new Error({'message': 'Session expired'}));
});
}
else
{
// session ok
}
});
}
}
You are using the callbacks just right.
return is used only to return from the current callback. When you call return next(...) you invoke the callback function and return the value it returns. Returns are often needed only to make sure you don't invoke a callback twice.
Note that you need to make sure every possible branch in your function will invoke the callback, otherwise your program will never proceed from verifyUserSession. In the code example you gave this happens two cases: 1) if session is ok, 2) if req.headers.sessionKey is not set. You should add callbacks for these branches as well.
Return statements in asynchronous coding are used only because they interrupt further execution of the block code. Basically this:
db.sessions.remove({sessionKey: req.headers.sessionKey}, function(err){
if (err)
{
return next(err);
}
return next(new Error({'message': 'Session expired'}));
});
is equivalent to:
db.sessions.remove({sessionKey: req.headers.sessionKey}, function(err){
if (err)
{
next(err);
return;
}
next(new Error({'message': 'Session expired'}));
return;
});
Note that last return is unnecessary.