nodejs cannot bind the property to the object - javascript

The property has been binded to the object questionaries list but it is not getting at the response time -
{
let cnt = 0;
questionnaire.find({"language" : defulatLang}, function (err, questionnaireList) {
if (questionnaireList !== null) {
async.eachSeries(questionnaireList,function(myquestions,callback){
questionnaire.find({'questionGroupId':"5a5ed4917c33629c1d383b8d"}, function (err, groups) {
questionnaireList[cnt].languagelist=groups;
// console.log("binded",questionnaireList[cnt].languagelist);
if(questionnaireList.length == cnt+1){
console.log("hello from response",questionnaireList)
res.json({
"code": 200,
"status": "success",
"message": "Questionnaire list",
"data": questionnaireList
});
}
cnt ++;
});
callback();
});
}
i want response in such a way that the binded property shoould also be send with response

You can do it like this -
let cnt = 0;
questionnaire.find({ "language": defulatLang }, function (err, questionnaireList) {
if (questionnaireList !== null) {
async.eachSeries(questionnaireList, function (myquestions, callback) {
questionnaire.find({ 'questionGroupId': "5a5ed4917c33629c1d383b8d" }, function (err, groups) {
if (err) {
return callback(err);
}
questionnaireList[cnt].languagelist = groups;
// console.log("binded",questionnaireList[cnt].languagelist);
if (questionnaireList.length == cnt + 1) {
console.log("hello from response", questionnaireList)
res.json({
"code": 200,
"status": "success",
"message": "Questionnaire list",
"data": questionnaireList
});
}
cnt++;
callback(null);
});
})
}
console.log("questionnaireList is null ", questionnaireList);
console.log("err ", err);
});
You have not handle the eachSeries callback properly.
Just Try this.

Related

How to add an item to a document collection using stored procedure

I want to add a collection of items to a cosmos DB document using stored procedure. There seems to be something wrong with the stored procedure that I have implemented. What is it that I am missing.
I get an error "Failed to deserialize stored procedure response or convert it to type 'System.Int32': Error converting value {null} to type 'System.Int32'"
I am using the below stored procedure to do the same. But In vain.
function spBulkAddStockCountItems(tenantId, stockCountId, stockCountItems) {
var collection = getContext().getCollection();
var collectionLink = collection.getSelfLink();
var count = 0;
// Validate input.
if (!stockCountItems) throw new Error("The array is undefined or null.");
var stockCountItemsLength = stockCountItems.length;
if (stockCountItemsLength === 0) {
getContext().getResponse().setBody(0);
return;
}
tryAdd(stockCountItems[count], callback);
function tryAdd(doc, callback) {
var queryDocument = "select * from c where c.tenantId='" + tenantId + "' and c.id='" + stockCountId + "'";
var isAccepted = collection.queryDocuments(collection.getSelfLink(), queryDocument, {},
function (err, documents, responseOptions) {
if (err) throw new Error("Error" + err.message);
if (documents.length != 1) throw "Unable to find both names";
stockCountDocument = documents[0];
stockCountDocument.items.push(doc);
console.log('done');
});
if (!isAccepted) getContext().getResponse().setBody(count);
}
function callback(err, doc, options) {
if (err) throw err;
// One more document has been inserted, increment the count.
count++;
if (count >= stockCountItemsLength) {
// If we have created all documents, we are done. Just set the response.
getContext().getResponse().setBody(count);
} else {
// Create next document.
tryAdd(stockCountItems[count], callback);
}
}
}
This is the document, to which I want to add the items.
{
"items": [],
"action": null,
"status": "InComplete",
"startTime": "2018-05-03T15:34:57.0237016+05:30",
"finishTime": "0001-01-01T00:00:00",
"supervisor": {
"userName": null,
"phoneNumber": null,
"pin": null,
"roleId": "00000000-0000-0000-0000-000000000000",
"outlets": null,
"swipeCardInfo": null,
"id": "00000000-0000-0000-0000-000000000000",
"name": "admin "
},
"outletId": "1884e251-7332-4ff6-9bc6-9b977521fd56",
"tenantId": "test#testimport6",
"type": "TIGER.Domain.Models.Stock.StockCount",
"auditLogs": null,
"isDeleted": false,
"id": "9c46c625-2448-4170-b7a2-23ced726f23f",
"name": null,
"_rid": "4FsbAPwjFQKcAgAAAAAAAA==",
"_self": "dbs/4FsbAA==/colls/4FsbAPwjFQI=/docs/4FsbAPwjFQKcAgAAAAAAAA==/",
"_etag": "\"0000ac54-0000-0000-0000-5aeaded30000\"",
"_attachments": "attachments/",
"_ts": 1525341907
}
I updated the stored procedure to and it works....
function spBulkAddStockCountItems(tenantId, stockCountId, stockCountItems) {
var collection = getContext().getCollection();
var collectionLink = collection.getSelfLink();
var response = getContext().getResponse();
var count = 0;
var stockCountItemsLength = stockCountItems.length;
// Validate input.
if (!stockCountItems) throw new Error("The array is undefined or null.");
if (stockCountItemsLength === 0) {
getContext().getResponse().setBody(0);
return;
}
tryAdd(stockCountItems[count], callback);
function tryAdd(stockCountItem, callback) {
var queryDocument = "select * from c where c.tenantId='" + tenantId + "' and c.id='" + stockCountId + "'";
var isAccepted = collection.queryDocuments(collection.getSelfLink(), queryDocument, {},
function (err, documents, responseOptions) {
if (err) throw new Error("Error" + err.message);
documents[0].items.push(stockCountItem);
var isReplaced = collection.replaceDocument(documents[0]._self, documents[0], callback);
if (!isReplaced) getContext().getResponse().setBody(count);
});
if (!isAccepted) getContext().getResponse().setBody(count);
}
function callback(err, doc, options) {
if (err) throw err;
// One more document has been inserted, increment the count.
count++;
if (count >= stockCountItemsLength) {
// If we have created all documents, we are done. Just set the response.
getContext().getResponse().setBody(count);
} else {
// Create next document.
tryAdd(stockCountItems[count], callback);
}
}
}

Run loop on the server with node.js

Let's say i need to constantly collecting some data from a lot of clients and in parallel running some complex loop that solving some stuff with this data. How can i do it? Should i just write this in my piece of code:
app.get('/', function(req, res) {
res.sendFile(__dirname + '/public/views/index0.html');
});
io.sockets.on('connection', function(socket) {
// SOME STUFF WITH THE SOCKET
socket.on('disconnect', function(data) {
//SOME OTHER STUFF
});
});
while(...) {
//THE LOOP STUFF
}
Or i need to use the setTimeout() and setInterval() functions? How can i do the loop on the server that runs in parallel with the callbacks' stuff?
Don’t use while for make it, this block a thread. setTimeout() will run only once. You need to use setInterval() function.
You can use the async module to handle the async operation with the callback or use promise to avoid callback.
Here how I handle a complex async for each operation, that might helpfull to you get idea handeling ayncs forach
var cond = { _schedule: schedule_id }; // find curse by schedule id
Course.find(cond, function (err, courses) {
if (err) {
callback({ "success": false, "message": "Not able to update" });
} else {
async.forEachLimit(courses, 1, function (course, coursesCallback) {
async.waterfall([
function (callback) {
var schedule_date = moment(change_data.date).format('YYYY-MM-DD') + "T00:00:00.000Z"
var Assignmentcond = {
assignment_schedule_order: {
$gte: schedule_date
},
_course: course._id,
_schedule: schedule_id,
_user: userid
};
Assignment.find(Assignmentcond)
.populate({
path: '_course',
})
.lean()
.sort({ assignment_schedule_order: 1 })
.exec(function (err, AssignmentList) {
if (err) {
callback(null, '');
} else {
//console.log("------------------AssignmentList---------------------------");
//console.log(AssignmentList);
async.forEachLimit(AssignmentList, 1, function (ThisAssignmentCell, ThisAssignmentCellCallback) {
async.waterfall([
function (callback) {
var SearchObj = items;
var lebelObject = {};
for (var i = 0, flag = 0, insert = 0; i < SearchObj.length; i++) {
if (SearchObj[i].date == ThisAssignmentCell.assignment_schedule_date) {
flag = 1;
}
if (flag == 1 && SearchObj[i].label != "") {
if (ThisAssignmentCell.day == SearchObj[i].day_index) {
insert = 1;
var lebelObject = SearchObj[i];
break;
}
}
}
callback(null, ThisAssignmentCell, lebelObject, insert);
},
function (ThisAssignmentCell, SearchObj, insert, callback) {
console.log('----------------------');
console.log('ThisAssignmentCell', ThisAssignmentCell);
console.log('SearchObj', SearchObj);
console.log('----------------------');
if (insert > 0) {
var query = { _id: ThisAssignmentCell._id },
fields = {
assignment_date: moment(SearchObj.date).format('MM/DD/YYYY'),
assignment_schedule_date: moment(SearchObj.date).format('YYYY-MM-DD'),
assignment_schedule_order: new Date(SearchObj.date),
day: SearchObj.day_index,
dayNum: SearchObj.weekday_num
},
options = { upsert: false };
Assignment.update(query, fields, options, function (err, affected) {
callback(null, '');
});
} else {
// var cond = { _id: ThisAssignmentCell._id};
// Assignment.remove(cond)
// .exec(function (err, cnt) {
// callback(null, '');
// });
}
}
], function (err, result) {
// result now equals 'done'
console.log('done')
ThisAssignmentCellCallback();
});
}, function (err) {
console.log("Assignment For Loop Completed");
callback(null, AssignmentList);
});
}
});
}
], function (err, result) {
// result now equals 'done'
console.log('done')
coursesCallback();
});
}, function (err) {
console.log("courses For Loop Completed");
});
}
});

How to pass socket to setTimeout and keep it open

I'm using NodeJS and using the
tls.connect(port, host, options, callback)
To get my socket to write to. I pass it through a async.waterfall and the socket.writable property stays set to true and I can write to the socket throughout. However, if I try to use it with setTimeout, it ends up being closed. Is there a way to keep it open or is my syntax incorrect?
This is one of the calls in async waterfall:
function (sock, err, callback) {
console.log(sock.writable); // this is true
setTimeout(function(sock) {
console.log(sock.writable); // this is false but I'd like it to be true so I can use it for more logic
}, 3000, sock);
}
I've also tried
function (sock, err, callback) {
console.log(sock.writable); // this is true
var sockz = sock;
setTimeout(function() {
console.log(sockz.writable); // this is false but I'd like it to be true so I can use it for more logic
}, 3000);
}
and this
function (sock, err, callback) {
console.log(sock.writable); // this is true
setTimeout(function(sock) {
console.log(sock.writable); // this is false but I'd like it to be true so I can use it for more logic
}.bind(this, sock), 3000);
// callback(null, sock);
}], function (err, sock) {
console.log(sock.writable);
}
But all of them print false. Is my syntax incorrect or does the socket automatically close in this scenario where I'm trying to get it to wait?
Edit
Full async.waterfall:
async.waterfall([
// insert record into db
function (acb) {
dbConn.query()
.insert(tableName, ["HOST", "SERVER_NAME", "DATE_CREATED"], [hostname, "test", currentTime])
.execute(function (err, result) {
if (err) {
componentStatus.database = false;
// pass the error down to run all the functions
acb(null, sockz, componentStatus, err);
} else {
componentStatus.resultId = result.id;
acb(null, sockz, componentStatus, null);
}
});
},
// read record back
function (sockz, componentStatus, err, acb) {
if (componentStatus.resultId < 0) {
acb(null, sockz, componentStatus, err);
} else {
dbConn.query().select("ID").from(tableName).where("ID=?", [componentStatus.resultId]).execute(function (err, rows, cols) {
if (err) {
componentStatus.database = false;
acb(null, sockz, componentStatus, err);
} else {
acb(null, sockz, componentStatus, err);
}
});
}
},
// send message to rabbit
function (sockz, componentStatus, err, acb) {
sendStatusMessage(currentTime, componentStatus.resultId, function (err1, result) {
if (err1) {
componentStatus.messaging = false;
var error = err + ", " + err1;
acb(null, sockz, componentStatus, error);
} else {
console.log("rabbit timeout");
console.log(sockz.writable);
setTimeout(function(sockz) {
console.log("In timeout");
console.log(sockz.writable);
}.bind(this, sockz), 3000); // wait for 3s to check record was consumed
}
});
}
], function (err, sockz, componentStatus, actualError) {
console.log(sockz.writable);
});
}
});
};
exports.sendStatusMessage = function(dateCreated, id, callback) {
var notification = { "dateCreated": dateCreated, "id": id };
_sendMsg("test.queue", notification, {"contentType": "application/json"}, function (err, result) {
if (err) {
callback(err, null);
} else {
callback(null, result);
}
});
}

Synchronize call in node.js

I am creating function in node.js from getting data from mongolab. It is just simple get method which return json
Here is my code:
app.get('/api/get_conversation_all_carer/:carer_id', function(req, res){
//Sender = user and receiver = carer
var values = [] ;
Conversation.aggregate([
{
$match: {
receiver_id: req.params.carer_id
}
},
{
$group: {
_id: "$sender_id",
}
}
],
function(err, result) {
if (err) {
console.log(err);
return;
}
for(var j = 0; j < result.length; j++) {
var object = {
"sender_id": result[j]._id,
"message": "",
"datetime": "",
"img": "",
"name":""
};
User.findOne({"_id": result[j]._id}, function(err, docs) {
object.img = docs.profile_pic;
object.name = docs.first_name;
});
Conversation.findOne({
$and: [
{
'receiver_id': req.body.carer_id
},
{
'sender_id': object.sender_id
}
]
},
{},
{
sort: {
'timer' : -1
}
},
function(err, docs) {
object.message = docs.message;
object.datetime = docs.timer;
values.push(object);
console.log("======= Inner =======");
}
);
}
console.log("====== OUT ======");
res = values;
}
);
});
Output:
====== OUT ======
====== Inner ======
I believe that Inner string should call first before Out, but here its happing reverse. I checked over other articals, but finding difficult to implement

Want to send request in sync in node.js

I have a scenario that I want to fetch data from collection and insert into an array and then return that array.
router.route('/user/:_id/host/:_id/joineeList').get(function(req, res) {
var finalList = [];
Host.findOne({
_id : req.params._id,
}, function(err, host) {
if (err) {
res.send(err);
} else {
var count = host.joinees.length;
for (var i = 0; i < count; i++) {
console.log(host.joinees[i].userid);
var ID = host.joinees[i].userid;
var CODE = host.joinees[i].status_code;
User.findOne({
_id : host.joinees[i].userid
}, function(err1, user) {
if (err1) {
console.log(err1);
} else {
finalList.push({
"userId" : ID,
"name" : user.name,
"profilepic" : user.profilepic,
"status" : CODE
});
console.log(finalList);
// finalList[i].add = ("userId",ID);
// finalList[i].add = ("name",user.name);
// finalList[i].add = ("profilepic",user.profilepic);
// finalList[i].add = ("status",CODE);
}
});
}
}
});
});
Now, what is happening is that my array is returned null but data is inserted in finalList array also. Here is the console output:
[]
888888888888888888888888888888888888888888
[ { userId: '5485ae1159a751697e000003',
name: 'aaaa',
profilepic: 'https://graph.facebook.com/986962491123456/picture?type=large',
status: 0 } ]
------------------------------------------
[ { userId: '5485ae1159a751697e000003',
name: 'aaaa',
profilepic: 'https://graph.facebook.com/123456781319929/picture?type=large',
status: 0 },
{ userId: '5485ae1159a751697g7654003',
name: 'ssss',
profilepic: 'link',
status: 0 } ]
------------------------------------------
You could use this library - https://github.com/caolan/async#eachSeries. The method is eachSeries
Your code would look like this:
var async = require('async');
router.route('/user/:_id/host/:_id/joineeList').get(function (req, res) {
var finalList = [];
Host.findOne({
_id: req.params._id
}, function (err, host) {
if (err) {
res.send(err);
} else {
var count = host.joinees.length;
var limits = [];
for (var i = 0; i < count; i++) {
limits.push(i);
}
async.eachSeries(limits, function (i, callback) {
console.log(host.joinees[i].userid);
var ID = host.joinees[i].userid;
var CODE = host.joinees[i].status_code;
User.findOne({
_id: host.joinees[i].userid
}, function (err1, user) {
if (err1) {
console.log(err1);
} else {
finalList.push({
"userId": ID,
"name": user.name,
"profilepic": user.profilepic,
"status": CODE
});
callback();
}
});
}, function() {
console.log(finalList);
});
}
});
});
Let me know if it helped
You probably need the parallel method of the async library (or maybe map) check it out https://github.com/caolan/async#parallel
Thanks to #Vitaliy Zurian. I have used the following code, by using counter in the for loop
router.route('/user/:_id/host/:_id/joineeList').get(function (req, res) {
var finalList = [];
Host.findOne({
_id: req.params._id
}, function (err, host) {
if (err) {
res.send(err);
} else {
var count = host.joinees.length;
var limits = [];
for (var i = 0; i < count; i++) {
limits.push(i);
}
async.eachSeries(limits, function (i, callback) {
console.log(host.joinees[i].userid);
var ID = host.joinees[i].userid;
var CODE = host.joinees[i].status_code;
User.findOne({
_id: host.joinees[i].userid
}, function (err1, user) {
if (err1) {
console.log(err1);
} else {
finalList.push({
"userId": ID,
"name": user.name,
"profilepic": user.profilepic,
"status": CODE
});
callback();
}
});
}, function() {
console.log(finalList);
});
}
});
});

Categories