Get empty Array in first loading page - node.js

When I call below function and show data at view of my ejs. There is no data at the first time of loading after the server start. But can get datas from second times of loading. That just only empty list on first time of loading after the server start. What is this matter? I am using redis as database. I also faced same error in using postgreSQL and sovled with
client.on('end', function(){
fn(_datas);
}.
but can't use that code now.
getAllDatas = function(fn){
client.smembers('db:contact:all', function(err, _uid){
if(err)
throw err;
else{
for(var i = 0; i < _uid.length; i++){
client.hgetall('db:contact:' + _uid[i], function(err, reply){
if(err)
throw err;
else{
_datas.push(reply);
}
});
}
}
});
fn(_datas);
_datas = [];
};

I solved as the below code by using setTimeout function. I know that is not the great answer but now can solved my error indeed.
getAllDatas = function(fn){
var _datas = [];
client.smembers('db:contact:all', function(err, _uid){
if(err)
throw err;
else{
for(var i = 0; i < _uid.length; i++){
client.hgetall('db:contact:' + _uid[i], function(err, reply){
if(err)
throw err;
else{
_datas.push(reply);
}
});
}
}
});
setTimeout(function(){
fn(_datas);
}, 100);
};

Related

Nodejs+Mongoose : find and update

I'm trying to search for a document in my mongo database then using the found document data to search another document and then update both. First document is to be saved after the second document is found.
But with my code the first document saves but doesnot saves updated data
My code :
var posts = {};
Posts.findOne({'url': req.body.url}, function(err, data){
posts = data;
//console.log(data);
Comments.findOne({'bucket': posts.bucket}, function(err, data){
var comment= data;
if(data.count>10){
posts.bucket = posts.bucket +1;
comment.bucket = comment.bucket +1;
}
comment.save(function(err, data){
if(err)
throw err;
});
});
posts.save(function(err, data){
if(err)
throw err;
res.json(data);
});
});
I observed that whatever changes is done in posts variable in Comments.findOne({...}) it remains local to it and doesnot effect outer posts varible, but it is just declared once. so how can i do this. Is something wrong in code? How do I do this!
First document is to be saved after the second document is found.
In your code you're saving the comment and the post in a parallel manner, you need to save the post after saving the document :
var posts = {};
Posts.findOne({
'url': req.body.url
}, function(err, data) {
posts = data;
//console.log(data);
Comments.findOne({
'bucket': posts.bucket
}, function(err, data) {
var comment = data;
if (data.count > 10) {
posts.bucket = posts.bucket + 1;
comment.bucket = comment.bucket + 1;
}
comment.save(function(err, data) {
if (err)
throw err;
posts.save(function(err, data) {
if (err)
throw err;
res.json(data);
});
});
});
});
Another important remark: you're creating a callback hell which leads to unknown behavior later. Please use async or promises instead of nesting callbacks.

Opening eventsources while keeping under the rate limit with Nodejs

my api only allows a maximum of 10 requests every second. I am trying to keep under this rate limit with async library. I have tried multiple functions but none of them work.
Pauseconnect and connectStream opens an eventstream for each item. let me know if you need to see their code.
async.queue --doesn't wait.
var cargo = async.queue(function (task, callback) {
setTimeout(
connectStream(task)
, 50000);
callback();
}, 1);
for(var j = 0; j < TeamList.length; j++) {
cargo.push(TeamList[j], function (err) {
});
async.eachLimit --stops at 5 and doesn't progress
async.eachLimit(TeamList, 5, pauseConnect, function(err){
if(err) {console.log(err);}
});
rate-limiter -- runs through all of them without waiting
limiter.removeTokens(1, function() {
for(var i=0; i< TeamList.length; i++){
connectStream(TeamList[i]);
}
});
async.each-- doesn't wait just runs through all of them
async.each(TeamList pauseConnect, function(err){
if(err) {console.log(err);}
});
You're missing the callback in the async.each, it should be (for example)...
async.each(TeamList pauseConnect, function(err, callback) {
if(err) {
console.log(err);
}
return callback();
});
If anyone is curious this worked for me
async.eachLimit(TeamList, 5, function(team, callback){
setTimeout(function(){
connectStream(team);
callback();
}, (5000));
}, function(err){
if(err) {console.log(err);}
});

Return image without saving on server (node.js)

I create an image in GraphicsMagick on Node.js and I want to give it back without saving on server. How may I do this?
I have this code:
var fs = require('fs');
var gm = require('gm');
var captchaImg = gm.(650, 200, "#ddff99f3");
for(var i = 0; i < 2; i ++){
for(var j = 0; j < 5; j ++){
...
}
}
.write("assets/images/c.jpg", function (err) {
console.log(err);
});
Write() create file on server. I can`t understand how return img without saving it in file... For example in base64.
This method solved the problem:
captchaImg.toBuffer(function (err, buffer) {
if (err) console.log(err);
else console.log('done!');
console.log(buffer.toString('base64'));
});
Thanks to all!
I hadn't use GraphicsMagick, but how about write to response?
.write(response, function (err) {
console.log(err);
});
If you use express. Maybe something like this.
exports.index = function(req, res){
gm('/path/to/image.jpg')
.resize(353, 257)
.autoOrient()
.write(res, function (err) {
if (!err) console.log(' hooray! ');
});
};

Not able to access result returned from mongoDb outside query

I am working with node.js using express and mongoDb.
I am trying to retrieve data from database "local" and collection "borrower" and pushing it into an empty array collectionOne. It is rendering this array on the view page.
I want to use _id pushed in an array b_ids from this output to make a call to company_details collection under same router .
The issue I am facing here is I am not getting any value in array b_ids when trying to access it under call to company_details collection.
The code is as below:
var collectionOne = [];
var collectionTwo = [];
var b_ids = [];
router.get('/fetch',function(req, res, next){
MongoClient.connect('mongodb://localhost:27017/local', function(err, db){
var collection = db.collection('borrower');
db.collection("borrower", function(err, collection) {
collection.find().toArray(function(err, result) {
if (err) {
throw err;
} else {
//console.log(result[0].first_name);
for (i=0; i<result.length; i++) {
collectionOne[i] = result[i];
b_ids[i] = result[i]._id;
}
}
});
db.collection("company_details", function(err, collection){
console.log(b_ids);
collection.find({borrower_id : {$in :b_ids}}).toArray(function(err, result){
if (err) {
throw err;
} else {
for (i=0; i<result.length; i++) {
collectionTwo[i] = result[i];
}
}
});
});
res.render('index',{data : collectionOne , data1 : collectionTwo});
});
});
});
Please suggest me how can I access the b_ids array here. Thanks in advance :)
The callback from toArray is asynchronous, i.e. will happen after your console.log line executes, therefore you need to re-arrange as follows:
var collectionOne = [];
router.get('/fetch',function(req, res, next){
MongoClient.connect('mongodb://localhost:27017/local', function(err, db){
var collection = db.collection('borrower');
db.collection("borrower", function(err, collection) {
collection.find().toArray(function(err, result) {
if (err) {
throw err;
} else {
for (i=0; i<result.length; i++) {
collectionOne[i] = result[i];
b_ids[i] = result[i]._id;
}
db.collection("company_details", function(err, collection){
console.log(b_ids);
collection.find({borrower_id : {$in :b_ids}}).toArray(function(err, result){
if (err) {
throw err;
} else {
for (i=0; i<result.length; i++) {
collectionTwo[i] = result[i];
}
res.render('index',{data : collectionOne , data1 : collectionTwo});
}
});
});
}
});
});
});
This ensures that the callback completes before you try and log / render it.
It is simple create a function with a callback function inside it as an argument
function returnBids(collection, callback){
collection.find().toArray(function(err, result) {
if (err)
throw err;
else
callback(result)
})
}
and you can access your result outside by calling the function returnbids() .i.e
returnBids(collection,function(b_ids){
console.log(b_ids)
})

Node.js : show process while copying files

I wrote a function to copy a directory to another... But there's a problem : I use callback function to send the copied size. This callback comes too early (before the end of the copy). I think the problem is that the process is asynchronous. Can you help me?
var fs=require('fs');
var copyDir=function copyDir(from, to, callback){
if(!fs.existsSync(to)){
fs.mkdirSync(to);
}
console.log(from+" ==> "+to);
var count = 0;
fs.readdir(from, function(err,files){
for(var i=0;i<files.length;i++){
var f = from+"/"+files[i];
var d = f.replace(from, to);
console.log(f+" ("+i+")"+ " : "+d);
if(!fs.existsSync(d)){
if(!fs.statSync(f).isFile()){
//fs.mkdirSync(f.replace(from, to));
count += fs.statSync(f).size;
console.log(f + " will make an inception!")
copyDir(f, f.replace(from, to), function(err, cp){callback(err, cp)});
}else{
var size = fs.statSync(f).size;
copyFile(f, f.replace(from, to), function(err){
if(err) callback(err, count)
});
count += size;
callback(null, count);
}
}
}
});
}
function copyFile(source, target, cb) {
fs.readFile(source, function (err, data) {
if (err) throw err;
fs.writeFileSync(target, data, function (err, data){
if(err) throw err;
cb(null, fs.statSync(source).size); //This callback comes before the copy end.
});
});
}
exports.copyDir = copyDir;
copyDir is called by:
io.sockets.on('connection', function(socket){
console.log('connection');
socket.on('startCopy', function(data){
sizeDir('templates', function(e, r){
copyDir('templates', 'tmp', function(err, cp){
console.log("copy % " + Math.round(100*cp/r));
socket.emit('copy', {prog: Math.round(100*cp/r)});
});
});
});
});
You can rewrite your else code with following:
(function() {
var size = fs.statSync(f).size;
copyFile(f, f.replace(from, to), function(err){
if(err) {
callback(err, count);
return;
}
count += size;
callback(null, count);
});
})();
But, you have a lot of synchronous function in your code. You should know about all caveats of this approach. This article may be helpful

Resources