Async parallel with object only last result - node.js

I'm having an issue with async parallel. This is my current code:
// Tasks object for async
var Tasks = {};
// Go through the items
for(index in items) {
var itemName = items[index];
Tasks[index] = function(callback) {
self._requestItem(currency, appID, itemName, function(err, item) {
if( err) {
callback(err, null);
return;
}
callback(null, { "name": itemName, "data": item });
});
}
}
// Go through tasks, using async parallel
this._async.parallel(Tasks, function(err, results) {
console.log(err, results);
});
Each items entry is unique. But when the parallel finishes it shows every result like the last one. For example if I have 3 items in items then async results outputs 0, 1 the same as 2.
null { '0':
{ name: 'Test 3',
data:
{ success: true,
price: 17.02 } },
'1':
{ name: 'Test 3',
data:
{ success: true,
price: 17.02 } },
'2':
{ name: 'Test 3',
data:
{ success: true,
price: 17.02 } } }
Why does it do this? If I use 2 items in items it again copies the result from 1 to 0.
Adding snippet of _requestItem as requested.
Manager.prototype._requestItem = function(currency, appID, itemName, callback) {
var self = this;
this._request({
uri: this._uri,
baseUrl: this._baseUrl,
json: true
}, function(err, res, body) {
if( ! err && res.statusCode !== 200) {
if(self._errorCodes[res.statusCode] !== undefined) {
callback(self._errorCodes[res.statusCode], null);
} else {
callback('Unsuccessful response (' + res.statusCode + '). Is the API having issues?', null);
}
} else if( ! err && res.statusCode === 200) {
callback(null, body);
} else {
callback(err, null);
}
});
}

No matter what is the content of the body of the _requestItem() function the value of the name attribute on the response array elements shouldn't be the same if the elements of the items array are unique.
The only error i can see is the fact that index is declared as a global variable but this shouldn't be the cause of the problem.
I suggest you to inspect the content of the items variable before the code enters the for loop (to see if it has been corrupted before this point). Debugging is a good idea in this case.
A better implementation would be:
var tasks = items.map(function(itemName){
return function(callback) {
self._requestItem(currency, appID, itemName, function(err, item) {
if( err) {
callback(err, null);
return;
}
callback(null, { "name": itemName, "data": item });
});
}
});
// Go through tasks, using async parallel
this._async.parallel(tasks, function(err, results) {
console.log(err, results);
});

Related

Empty data object when deleting item from dynamodb

According to the docs I should get a data structure with the item as it was prior to the deletion (in case there was no error)
I do check there was no error but I get an empty object for data:
docClient.delete(params, (err, data) => {
if (err) {
console.error('Error tring to delete item:' + err);
callback(err, null); // error
} else if (!data.Items || data.Items.length == 0) {
console.info(JSON.stringify(data));
callback(null, null); // no items
} else {
console.info(JSON.stringify(data));
callback(null, data.Items[0].ExposeStartTimestamp);
}
});
Both prints empty json: {}
In order for the deleted data to appear in the response, the request should contain the attribute ReturnValues with value ALL_OLD.
var params = {
TableName: 'TableName',
Key: {
HouseId: houseId
},
ReturnValues: 'ALL_OLD'
};

async function is not working in node js

I am trying to develop an APP in which I have to increase or decrease the user count according to their hobbies/interest in the master list. I am doing it in Node js with the help of loopback. Here is my code, in which I am giving two interests(i.e sketching and horse-riding):
async.forEach(data, function (interest) {
console.log("Interest is", interest);
Interest.findOne({
where:
{
'name': interest
}
}, function (err, interestObj) {
if (err) {
//return callback(err, null);
console.log("error", err);
}
else {
//return callback(null, response);
console.log("found", interestObj);
if (!interestObj) {
Interest.create({ "name": interest, "count": 1 }, function (err, response) { });
}
else {
_count = interestObj.count + 1;
interestObj.updateAttribute('count', _count, function (e, r) { });
}
}
});
// return callback(null, {});
},function(err){
console.log("success..!!")
});
}
but it is showing me only one of them in output. Here is output:
data is [ 'horse-riding', 'skeching' ]
Interest is horse-riding
Interest is skeching
found { name: 'horse-riding', count: 1, id: 59ccff0765055a212491a6bc }
found null
I think the async function is not working properly with forEach loop in this, But I am not getting where the code went wrong. I want to show all the interest given by the user, so what course of actions should I take to do it?? Thanks in advance..!!:)
It is working now...!!!
async.each(data, function (interest, callback2) {
console.log('Processing ', interest);
Interest.findOne({
where:
{
'name': interest
}
}, function (err, interestObj) {
if (err) {
console.log("error", err);
callback2(err);
}
else {
console.log("found", interestObj);
if (!interestObj) {
Interest.create({ "name": interest, "count": 1 }, function (err, response) { });
}
else {
_count = interestObj.count + 1;
interestObj.updateAttribute('count', _count, function (e, r) { });
}
callback2();
}
});
}, function (err) {
if (err) {
console.log('Failed to process', err);
} else {
console.log('All interests have been processed successfully');
}
return callback(err);
})
};

I need help about Asynchronus call in node.js with Mongodb, i need to call synchronous method for further processing of data

calling id from mongodb with callback function
var GetID = function (nameval, callback) {
console.log(nameval);
console.log("munesh hello");
GenerateID.find({ "id_name": nameval }, {
"id_code": 1,
"id_value": 1, "_id": 0
}, function (err, genvalue) {
if (err) {
console.log('hello');
}
else {
if (genvalue === null) {
callback(err, false);
}
else {
callback(err, true);
}
}
console.log(genvalue);
});
};
and calling above method so we need
so we need id from GenerateID.GetID and do our own work.
var region_id = GenerateID.GetID(name, function (error, result) {
if (error) {
console.log("getting any error");
} else {
console.log(region_id);
if (!result) {
console.log('data is not coming');
} else {
console.log('data is coming');
}
}
});
You have a number of issues. In the first piece of code, you need to pass the actual value when calling the callback.
In the second, you need to set region_id = result.
Ideally you would do this using promises as demonstrated below.
var GetID = function(nameval){
return new Promise((resolve,reject) => {
console.log(nameval);
console.log("munesh hello");
GenerateId.find({ "id_name" : nameval },{"id_code":1 , "id_value":1, "_id":0},
function( err , genvalue ) {
console.log(genvalue);
if (err) {
console.log('hello');
return reject()
}
if (genvalue == null) { return resolve(false); }
return resolve(genValue);
});
});
}
var GetIDPromise = GenerateId.GetID(name);
GetIDPromise.then(
genValue => {
if ( genValue == false ){
console.log('data is not coming');
// handle region id not being available. Perhaps return and show an error
}else{
var region_id = genValue;
// continue execution and use region id.
}
},
error => {
console.log("getting any error");
}
)

mongodb native driver issues on filter queries

I'm having trouble getting to use the query mongodb.
I do not know if I could detail the method used is being sent an object, but is being rejected or sometimes the filter back empty.
it always returns me an error:
MongoError: query selector must be an object
The entry of the query is being thereby:
{ filter: 'f', limit: '5', page: '1', sort: '-posted' }
My server Route:
exports.findAll = function(req, res, next) {
var locals = {},
section = req.params.section,
query = req.query,
filter = {};
if(query.filter) {
filter = query.filter.replace(/"(\w+)"\s*:/g, '$1:');
filter = filter.replace(/["]/g, "'");
}
console.log(filter);
delete query.filter;
async.series([
function(callback) {
MongoClient.connect(url, function(err, db) {
if (err) return callback(err);
locals.collection = db.collection(section);
callback();
});
},
function(callback) {
locals.collection.count(filter, function (err, result){
if (err) return callback(err);
locals.count = result;
callback();
});
},
function(callback) {
//var cursor = locals.collection.find(filter);
var cursor = locals.collection.find(filter, req.query);
// if(req.query.order) {
// cursor = cursor.sort();
// }
//
// if(req.query.limit) {
// cursor = cursor.limit(Math.abs(req.query.limit));
//
if(req.query.page) {
cursor = cursor.skip(Math.abs(req.query.limit) * --req.query.page);
}
// }
cursor.toArray(function(err, docs) {
if (err) return callback(err);
locals.docs = docs;
callback();
});
}
],
function(err) { //This function gets called after the three tasks have called their "task callbacks"
if (err) return next(err);
// Here locals will be populated with 'count' and 'docs'
res.json({
count: locals.count,
data: locals.docs
});
});
};
i change the function server, adn now my response is:
{ filter: {situation: 't'}, limit: '5', page: '1', sort: '-posted' }
And same error :( :(

Callback function in Nodejs

I have function
var checkTokenIsExpired = function(name, token, response) {
LoginToken.find( { name: name, series: token }, function(error, info){
console.log("info: ", info[0]['expire']);
if (error) {
// response.send("error: %s}", error);
response(error);
}
if (info.length > 0) {
var expire = new String(info[0]['expire']);
// expire = expire.substr(0,26);
var date = new Date(expire);
if (date >= new Date()) {
// response.send("{info: success" );
response("success");
}
else{
// response.send("error: token-has-expired");
response("token-has-expired");
}
console.log("Response: ", info);
}
else {
response(null);
}
} );
}
To check token is expired or not? It will return a string.
And I call this function in here
exports.updateAccount = function(newData, callback)
{
Accounts.find({name:newData.body.name}, function(err, docs){
if (err) {
callback.send('{error: ' + String(err) + "}");
}
if (docs.length==0 || !docs) {
callback.send("{error: NULL }");
}
else {
checkTokenIsExpired(newData.body.name, newData.body.token, function(error, info){
if (error){
callback.send("{error: " + error + "}");
// I want to get info here }
console.log("check token: ", info);
// check info of token is expired or not
if (info!=null && info!="token-has-expired") {
var updateString = "";
if (newData.body.screen_name){
Accounts.update( {'name': newData.body.name},
{
"screen_name" : newData.body.screen_name
},
{ 'upsert' : true },
function (err, numberAffected, raw) {
if (err) return handleError(err);
});
}
if (newData.body.email){
Accounts.update( {'name': newData.body.name},
{
"email": newData.body.email
},
{ 'upsert' : true },
function (err, numberAffected, raw) {
if (err) return handleError(err);
});
}
if (newData.body.password == ''){
} else{
var password = encodePassword(newData.body.password, docs[0]['salt']);
Accounts.update( {'name': newData.body.name},
{
"hassedPass" : password,
},
{ 'upsert' : true },
function (err, numberAffected, raw) {
if (err) return handleError(err);
});
}
}
});
}
I want to get the info when call checkTokenIsExpired but when I console.log("info", info) it return undefined.
in checkTokenIsExpired, you need to pass info to the response callback otherwise it is not in scope of your second code.
at least in the case where you have success:
response("success", info);
Instead of passing "success", you'd typically pass null to indicate there is no error.
I have solved problem
checkTokenIsExpired(newData.body.name, newData.body.token, function(error, info)
because it will take 1 parameter but I put 2
Change it into checkTokenIsExpired(newData.body.name, newData.body.token, function(info)
It will correct :D

Resources