How can i use the for loop with findOne from mongoose in node.js, maybe have other logic that i can do the same thing?
data = { _id: '598b4e9abe74280be0b0cb1b' }
{ _id: '598b4ec1be74280be0b0cb1c' }
{ _id: '598b4fa8be74280be0b0cb1d' }
{ _id: '5992feccdad6db0c603b260d' }
{ _id: '5995e4ce0b38ba123cf06654' };
notification = new Array();
for (var i = 0; i < data.length; i++) {
Message.findOne({ from: data[i]._id, to:socket.handshake.session.passport.user }, function(err, message){
if (err){
console.log('error');
}
if(!message.length){
console.log('no message!!');
}else{
notification.push(message);
}
});
}
If you can transform your input data into an array you can do this:
var data = [ObjectId('598b4e9abe74280be0b0cb1b'),
ObjectId('598b4ec1be74280be0b0cb1c'),
ObjectId('598b4fa8be74280be0b0cb1d'),
ObjectId('5992feccdad6db0c603b260d'),
ObjectId('5995e4ce0b38ba123cf06654')];
Message.find({from: {$in: data}, to:socket.handshake.session.passport.user})
Related
I am trying to redirect to '/admin' route if the required data gets updated successfully but I am getting the error that res.redirect is not a function. I have tried writing return res.redirect also but it is also not working. Node experts, please help. Here I am just finding the student record on it's reg.no. basis and updating the record with its marks and redirecting to the admin page.
app.post('/admin/midterm/marks',(req,res)=>{
var m_written=[];
var m_practical=[];
var myjson=JSON.stringify(req.body);
course.subjects.map(sub=>{
if(!Array.isArray(req.body[`${sub}`]))
{
var p={subject:sub,mark:req.body[`${sub}`]}
m_written.push(p);
}
else{
var p={subject:sub,mark:req.body[`${sub}`][0]};
var q={subject:sub,mark:req.body[`${sub}`][1]};
m_written.push(p);
m_practical.push(q);
}
});
var first={
sem:course._id,
marks_sem:[{
term:ms,
m_written:m_written,
m_practical:m_practical
}]
}
if(!StudentRecord.total.length )
{
Student.updateOne({_id:check_Id},{total:first},function(err,res){
if(err)
{console.log("error");}
res.redirect('/admin');
});
}
else{
var flag=0;
StudentRecord.total.map(record=>{
if(record.sem==required_sem)
{
flag=1;
record.marks_sem.push(first.marks_sem);
Student.updateOne({_id:check_Id},{total:StudentRecord.total},function(err,res){
if(err)
{console.log("error");}
res.redirect('/admin');
});
}
});
if(flag==0)
{
StudentRecord.total.push(first);
Student.updateOne({_id:check_Id},{total:StudentRecord.total},function(err,res){
if(err)
{console.log("error");}
res.redirect('/admin');
});
}
}});
You override res in your callbacks. Name the second parameter in the callbacks result and everything will work fine.
app.post("/admin/midterm/marks", (req, res) => {
var m_written = [];
var m_practical = [];
var myjson = JSON.stringify(req.body);
course.subjects.map((sub) => {
if (!Array.isArray(req.body[`${sub}`])) {
var p = { subject: sub, mark: req.body[`${sub}`] };
m_written.push(p);
} else {
var p = { subject: sub, mark: req.body[`${sub}`][0] };
var q = { subject: sub, mark: req.body[`${sub}`][1] };
m_written.push(p);
m_practical.push(q);
}
});
var first = {
sem: course._id,
marks_sem: [
{
term: ms,
m_written: m_written,
m_practical: m_practical,
},
],
};
if (!StudentRecord.total.length) {
Student.updateOne({ _id: check_Id }, { total: first }, function (err, result) {
if (err) {
console.log("error");
}
res.redirect("/admin");
});
} else {
var flag = 0;
StudentRecord.total.map((record) => {
if (record.sem == required_sem) {
flag = 1;
record.marks_sem.push(first.marks_sem);
Student.updateOne(
{ _id: check_Id },
{ total: StudentRecord.total },
function (err, result) {
if (err) {
console.log("error");
}
res.redirect("/admin");
}
);
}
});
if (flag == 0) {
StudentRecord.total.push(first);
Student.updateOne(
{ _id: check_Id },
{ total: StudentRecord.total },
function (err, result) {
if (err) {
console.log("error");
}
res.redirect("/admin");
}
);
}
}
});
I got a data from MySQL and push it into new Array but it when I log it. It doesn't have any data. I use for loop to get each data from DB and I don't know how to push RowDataPacket into new Array.
Or is there any way to combine two SQL into one SQL line?
router.get(`/find-users/:queryString`, function(req, res, next) {
let queryString = req.params.queryString;
db.query(
`SELECT distinct userId from project WHERE keyword like "%${queryString}%"`,
function(error, data) {
if (error) {
console.log(error);
}
// console.log(data);
let userArray = [];
for (let i = 0; i < data.length; i++) {
db.query(
`SELECT * FROM user WHERE loginId='${data[i].userId}'`,
function(error, userData) {
if (error) {
console.log(error);
} else {
console.log("-----------------------");
console.log(userData[0]);
// userArray[i] = userData;
userArray.push(userData[0]);
}
}
);
}
console.log(`-------`);
console.log(userArray);
console.log(`-------`);
}
);
});
I have to make array like this.
[ RowDataPacket {
loginId: '박동찬',
displayId: '107688875506148574770',
name: '박동찬',
bio: 'NO BIO',
RowDataPacket {
loginId: 'jaagupkymmel',
displayId: '1156051',
name: 'Jaagup Kümmel',
bio: 'NO BIO' }
]
But it only returns like this
Result
-------
[]
-------
const {promisify} = require('util')
router.get(`/find-users/:queryString`, async function (req, res, next) {
const query = promisify(db.query).bind(db);
let queryString = req.params.queryString;
const data = await query(`SELECT distinct userId from project WHERE keyword like "%${queryString}%"`)
if (!data) {
console.log("error");
}
// console.log(data);
let userArray = [];
for (let i = 0; i < data.length; i++) {
const userData = await query(`SELECT * FROM user WHERE loginId='${data[i].userId}'`)
if (!userData) {
console.log("error");
} else {
console.log("-----------------------");
console.log(userData[0]);
// userArray[i] = userData;
userArray.push(userData[0]);
}
}
console.log(`-------`);
console.log(userArray);
console.log(`-------`);
});
use this instead
function(error, userData, fields)
and you get an array like shown here https://www.w3schools.com/nodejs/nodejs_mysql_select.asp
And please read up on sql injection and node.js Preventing SQL injection in Node.js
in addition to above answer,
[{
RowDataPacket: {
loginId: '박동찬',
displayId: '107688875506148574770',
name: '박동찬',
bio: 'NO BIO',
RowDataPacket: {
loginId: 'jaagupkymmel',
displayId: '1156051',
name: 'Jaagup Kümmel',
bio: 'NO BIO' }
}
}]
the json should be key value pair other it wont work.
I am trying to query one collection, get IDs from that and with that I am querying another collection and send the response. No issue in that. My issue is I am using foreach, so I am trying to get the value out of block and send the response. But it's throwing null. I consoled the value inside the block, its giving the response but I couldn't access the value out of the block.
Code
getDetails = async (req, res) => {
let data: any[] = [];
await employee.find({
_id: new mongoose.Types.ObjectId(req.body.id)
}, (err, obj) => {
if (err) {
console.log("No Such Employee")
} else {
obj.forEach(element => {
employer.find({
user: new mongoose.Types.ObjectId(element.user)
}, (err, details) => {
if (err) {
console.log("No such employer")
} else {
for (var i = 0; i < detail.length; i++) {
let p_info = {
"id": detail._id,
"fname": details[i].fname "lname": details[i].lname "phone": details[i].phone,
"email": details[i].email,
}
data.push(p_info); // I can get value here
}
}
})
});
res.send(data); // Cannot get value here
}
});
}
return response only when all your asynchronous db calls are done. see below:
getDetails = async(req, res) => {
let data = [];
let employees;
try {
employees = await employee.find({
_id: new mongoose.Types.ObjectId(req.body.id)
});
} catch (err) {
console.log("No Such Employee");
}
let emp_len = employees.length;
employees.forEach((emp_obj, idx) => {
let details = await employer.find({
user: new mongoose.Types.ObjectId(emp_obj.user)
});
for (var i = 0; i < patient.length; i++) {
let p_info = {
"id": patient._id,
"fname": details[i].fname,
"lname": details[i].lname,
"phone": details[i].phone,
"email": details[i].email,
}
data.push(p_info); // I can get value here
}
if (emp_len == idx + 1) {
res.send(data); // Cannot get value here
}
});
}
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
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);
});
}
});
});