I want to iterate insert to db. Right after the iteration is done, I want to generate success message and redirect user to the specific page. That's why I use async package.
Here's my code:
async.forEachOf(venue_1_split, function (venue, key, callback) {
pool.query("INSERT INTO peminjaman_venue VALUES (?,?,?,?,?,?,?)",
[id_event, venue, id_google_calendar, waktu_mulai_1, waktu_selesai_1, tanggal_peminjaman_1, tanggal_peminjaman_1],
function(err, rows, fields){
if (err) throw err;
});
req.flash('message_success', 'Berhasil mengajukan event');
callback(res.redirect('/pengajuan_event'));
}, function (err) {
if (err) console.error(err.message);
});
It works but seems to be not correct. First, it returns error `
"Can't set headers after they are sent"
And when i checked my db it only inserted 2 rows. The loop stopped on 2nd iteration. Can you fix my code. Thank you.
`
You are redirecting to /pengajuan_event after every insert. Try following code.
async.forEachOf(venue_1_split,
function (venue, key, callback) {
pool.query("INSERT INTO peminjaman_venue VALUES (?,?,?,?,?,?,?)",
[
id_event,
venue,
id_google_calendar,
waktu_mulai_1,
waktu_selesai_1,
tanggal_peminjaman_1,
tanggal_peminjaman_1
],
callback(err, rows, fields)
)}, function (err) {
if(err) {
console.error(err.message);
} else {
req.flash('message_success', 'Berhasil mengajukan event');
res.redirect('/pengajuan_event')
}
}
);
Related
User.find().exec(function (err, users) {
if (err){
callback(err);
} else {
callback(users);
}
});
User.find(function (err, users) {
if (err) {
callback (err);
} else {
callback(users);
}
});
What is the benefit of using the top code? both seem to work equally well
They are identical and there's no benefit in your example
When you do not pass a callback to find function it won't execute but instead returns a query then you need to use exec()
var query = User.find();
now you can add some more criteria
query.where({age: 15});
and some more
query.select({name:1}); // or {firstname:1, lastname:1} etc.
now you've built up your query so to get the results you need to execute it.
query.exec(function(err, users){
});
But you can also do this like
User.find({age:15}, {name:1}, function(err, users){
});
Above is identical to
User.find({age:15}, {name:1}).exec(function(err, users){
});
since there's no callback in find function it will return query which means no results, exec will give you the results
I'm trying to export one function this way:
exports.query = function(request){
conn.query(request, function(err, rows, fields){
if(err) console.log(err);
return rows[0].id;
});
}
and using it:
var mysql = require('./mysql');
console.log(mysql.query('SELECT * FROM tablename'));
Proceeding this way for getting a result involves undefined as output.
How do I to fix this, please?
Note that when I just type console.log(rows[0].id) instead of return rows[0].id it sends back 123.
Thanks in advance!
In your example, the output is being returned to the anonymous function of the database query instead of the caller of the module. You can use a callback to return output to the caller of the module.
exports.query = function(request, callback){
conn.query(request, function(err, rows, fields){
if (err) {
callback(err);
} else {
callback(null, rows[0].id);
}
});
}
Then call it like
var mysql = require('./mysql');
mysql.query('SELECT * FROM tablename', function(err, results){
if (err) {
console.error(err);
} else {
console.log(results);
}
});
That's a problem of synchrony.
the conn.query function returns undefined because it finish its execution before the results are fetched (like almost any i/o related operation on js/node).
One possible solution to that, is to provide a callback to your query function.
exports.query = function(request, cb){
conn.query(request, function(err, rows, fields){
// some "special" processing
cb(err, rows, fields);
});
};
If you're not familiar with async functions, take a look on some articles about that:
http://justinklemm.com/node-js-async-tutorial/
https://www.promisejs.org/
thanks for your help...struggling big time with how to handle this properly. I'm in async now, having given up on my ability to write the callbacks properly. I have snippet where I'm passing a set of random numbers (eachrecord) and passing them through to a mongoose call. Trying to create a data set from the multiple queries I pass.
My issue is that no matter what I've done for 4 hours, the "newarray" variable is always empty.
Thank you for your help -
async.forEach(arLimit, function(eachrecord, callback){
newarray = new Array;
var query = UGC_DB_Model.find({}).skip(eachrecord).limit(-1);
query.execFind(function (err, data) {
if (err)
console.log(err);
else {
newarray.push(data);
}
});
callback(null, newarray);
}, function(err, result) {
if (err) return next(err);
console.log("(it's empty): " + result);
});
There are several issues with your code:
async.forEach isn't meant to 'generate' results, that's what async.map is for;
you need to call the callback only when execFind is done, and not immediately after calling it;
your newarray is probably not necessary;
So try this instead:
async.map(arLimit, function(eachrecord, callback){
var query = UGC_DB_Model.find({}).skip(eachrecord).limit(-1);
query.execFind(function (err, data) {
if (err)
callback(err); // pass error along
else {
callback(null, [ data ]);
// although I think you mean this (because 'data' is probably an array already)
// callback(null, data);
}
});
}, function(err, result) {
if (err) return next(err);
console.log("(it's empty): " + result);
});
I want to use async to make node.js work something in order, first query two rates from mongodb,then use these rates to compute two new rate:
async.series([
function(callback){
db.collection('heros',function(err,collection){
if(err){
console.log(err);
}
if(!err){
console.log("2 collection fetched!");
collection.findOne({'id':win},function(err,result){
if (err) throw err;
rate1=result.rate;
console.log("win-rate:"+rate1);
});
collection.findOne({'id':lose},function(err,result){
if (err) throw err;
rate2=result.rate;
console.log("lose-rate:"+rate2);
});
}
});
callback(null);
}, function(callback){
var Ea= 1/(1+Math.pow(10,(rate2-rate1)/400));
var Eb= 1/(1+Math.pow(10,(rate1-rate2)/400));
var ra= rate1+16*(1-Ea);
var rb= rate2+16*(0-Eb);
console.log("ra:"+ra);
console.log("rb:"+rb);
callback(null);
},
function(callback){
db.collection('heros',function(err,collection){
if(!err){
collection.update({'id':win},{$set: {rate:ra}},function(err,result){
if(err) throw err;
if(!err){
console.log("update successful");
}
});
collection.update({'id':lose},{$set:{rate:rb}},function(err,result){
if(err) throw err;
if(!err){
console.log("update successful");
}
});
}
});
callback(null);
}
]);
but when I run it, it shows error messages:
ReferenceError: ra is not defined
it seems that nodejs jumps to computing or updating without waiting for the query complete.
You're declaring the variables like ra inside of a function block, so they're scoped to that function and unavailable elsewhere. You'd need to put them somewhere more accessible. For example, you could put them in a global variable:
var ra;
async.series([ ... ]);
Further, when you use series, you should call the callback function only when all of the work for that step has completed.
For example, one task should look like this:
db.collection('heros',function(err,collection){
if(err){
console.log(err); // log the error
callback(err); // call the async call back with the error
return; // stop
}
console.log("2 collection fetched!");
collection.findOne({'id':win},function(err,result){
if (err) { callback(err); return; } // again, handle error
rate1 = result.rate; // grab results
console.log("win-rate:"+rate1); // log
callback(null, rate1); // now indicate complete by calling
});
});
As you've got multiple async function calls within a single task, you may want to split them to multiple tasks or consider using the parallel function as well. You could even use parallel within one of the other tasks in the series call to handle the case where you have two findOne calls that need to be made.
I may be misunderstanding something, but on the client I have a request sent to the server. Something like:
$.post("/resources/remove", {"id": 52024e25b26d39f931000003})
On the server I have
Resource.remove({_id: request.body.id})
The "ID" is correct and using Resource.find with the same arguments returns the record I want to remove. However, when this is run it removes all Resource records. The return value of exec(function (err, returnValue) is the number of Resource records that were there, so it is definitely removing all of them. Using Remove.(request.body.id) does the same thing.
Do I need to do anything else to make sure that only the record with the corresponding _id is removed? If the entry is invalid why is it removing all records?
Try using Resource.findOneAndRemove Reference
I've never used that but this is what I use and it works perfectly for me
PostModel.findOne({_id: id}, function (err, result) {
if (err) {
throw err;
}
if (result) {
PostModel.remove({_id: id}, function (err, result) {
if (err) {
throw err;
}
res.json(200, result);
});
}
});