associative array show empty value - node.js

hi everyone I tried to develop chat app using node js and socket.io for back end , my problem is empty value of associated array
socket.on('nickName', (data) => {
console.log(data)
var roomId;
con.query("SELECT user_id FROM nickname WHERE user_id = '" + String(data) + "'", (err, result) => {
if (err) {
throw err;
}
console.log(result)
if (result == undefined || result[0] == undefined) {
con.query("INSERT INTO nickname (user_id,socket_id) VALUES ('" + data + "','" + socket.id + "')")
} else {
con.query("UPDATE nickname SET socket_id = '" + socket.id + "' WHERE user_id = '" + data + "' ", (err, result) => {
})
}
})
con.query("SELECT * FROM room WHERE user_id = '" + data + "'", (err, result) => {
if(err){
throw err;
}else{
io.to(socket.id).emit('getChatList', { "chatList": result })
var unread = {}
result.forEach(Element=>{
roomId = Element.room_name
con.query("SELECT COUNT(*) FROM message WHERE room_id = '"+roomId+"' AND seen=0 AND to_user='"+data+"'",(err,unseen)=>{
if(err){
throw err;
}else{
// I trying set value to unread array
unread[roomId] =unseen[0]['COUNT(*)'] ;
// unread array work correctly
console.log(unread)
}
})
// problem is here print unread empty ({})in
// console.
console.log(unread)
})
}
})
});
unread array show empty value but when I put for example unread['A'] ='C' ; out of query block everything works fine , anyone can help me?

I solved my problem by using async.each() instead of result.forEach()
socket.on('nickName', (data) => {
console.log(data)
var roomId;
clients[data] = socket.id;
con.query("SELECT user_id FROM nickname WHERE user_id = '" + String(data) + "'", (err, result) => {
if (err) {
throw err;
}
console.log(result)
if (result == undefined || result[0] == undefined) {
con.query("INSERT INTO nickname (user_id,socket_id) VALUES ('" + data + "','" + socket.id + "')")
} else {
con.query("UPDATE nickname SET socket_id = '" + socket.id + "' WHERE user_id = '" + data + "' ", (err, result) => {
})
}
})
con.query("SELECT * FROM room WHERE user_id = '" + data + "'", (err, result) => {
if(err){
throw err;
}else{
io.to(socket.id).emit('getChatList', { "chatList": result })
var unread = {};
asyncc.each(result,function(Element,callbackk){
roomId = Element.room_name
console.log(Element)
con.query("SELECT COUNT(*) FROM message WHERE room_id = '"+Element.room_name+"' AND seen=0 AND to_user='"+data+"'",(err,unseen)=>{
if(err){
throw err;
}else{
console.log(unseen)
console.log(Element.room_name)
unread[Element.room_name] = unseen[0]['COUNT(*)'] ;
}
callbackk();
})
},function(er){
console.log(unread)
})
}
})
});

Related

LDAP authentication using ldapjs in nodejs

Am a newbie to node.js, have somewhat figured out the LDAP authentication. Here am trying to retrieve employee ID from the search but none of the search entries are fetched though the passed credentials are bounded successfully , not sure where i'm mislead. If someone could help me out in it would be of a great help!
Below are the result sets of the code snippet:
Reader bind succeeded
Search results length: 0
Search
retval:{"messageID":2,"protocolOp":"LDAPResult","status":0,"matchedDN":"","errorMessage":"","referrals":[],"controls":[]}
No unique user to bind
ldapRoute.route('/ldap').post((req, res, next) => {
var result = "";
var email =req.body.email;
var client = ldap.createClient({
url: 'ldap://******'
});
var opts = {
filter: '(sAMAccountName='+ email + ')',
attributes: ['sAMAccountName']
};
var username = 'ii' + "\\" + email;
client.bind(username, req.body.password, function(err) {
if (err){
result += "Reader bind failed " + err;
res.send(result);
return;
}
else{
result += "Reader bind succeeded\n";
}
client.search('OU=emp,dc=i,dc=ac,dc=com', opts, function(err, searchRes) {
var searchList = []
if (err) {
result += "Search failed " + err;
res.send(result);
return;
}
searchRes.on("searchEntry", (entry) => {
result += "Found entry: " + entry + "\n";
searchList.push(entry);
});
searchRes.on("error", (err) => {
result += "Search failed with " + err;
res.send(result);
});
searchRes.on("end", (retVal) => {
result += "Search results length: " + searchList.length + "\n";
for(var i=0; i<searchList.length; i++)
result += "DN:" + searchList[i].employeeID + "\n";
result += "Search retval:" + retVal + "\n";
if (searchList.length == 1) {
client.bind(searchList[0].employeeID, req.body.password, function(err) {
if (err)
result += "Bind with real credential error: " + err;
else
result += "Bind with real credential is a success";
res.send(result);
}); // client.bind (real credential)
} else {
result += "No unique user to bind";
res.send(result);
}
});
});
});
});
The issue was in the filters and for some strange reasons the 'end' got fired before hitting the 'searchEntry', debugging it helped me to resolve the issue.
//Filter
var opts = {
filter: '(sAMAccountName=' + email+')',
scope: 'sub',
attributes: ['employeeID']
};
//Search
client.search('OU=empl,dc=ii,dc=ac,dc=in', opts, function(err, searchRes)
{
if (err)
{
result += "Search failed " + err;
res.send(result);
return;
}else{
searchRes.on("searchEntry", (entry) =>
{
result += "Found entry: " + entry.object.employeeID;
res.send(result);
}
/ ........../
} });

Getting ENOENT error using node.js and MySQL

I am following the node tutorial on https://dev.to/achowba/build-a-simple-app-using-node-js-and-mysql-19me , to build a node application with Mysql. I'm getting the error "ENOENT path: public/assets/img/image name" which I have been able to trace to the line uploadedFile.mv('public/assets/img/${image_name}', (err ) => { in the file player.js.
I have tried fs.writeFile and fs.copyFile to no avail. Any help will be appreciated.
PLAYER.JS
const fs = require('fs');
module.exports = {
addPlayerPage: (req, res) => {
res.render('add-player.ejs', {
title: "Welcome to Socka | Add a new player"
,message: ''
});
},
addPlayer: (req, res) => {
if (!req.files) {
return res.status(400).send("No files were uploaded.");
}
let message = '';
let first_name = req.body.first_name;
let last_name = req.body.last_name;
let position = req.body.position;
let number = req.body.number;
let username = req.body.username;
let uploadedFile = req.files.image;
let image_name = uploadedFile.name;
let fileExtension = uploadedFile.mimetype.split('/')[1];
image_name = username + '.' + fileExtension;
let usernameQuery = "SELECT * FROM `players` WHERE user_name = '" + username + "'";
db.query(usernameQuery, (err, result) => {
if (err) {
return res.status(500).send(err);
}
if (result.length > 0) {
message = 'Username already exists';
res.render('add-player.ejs', {
message,
title: "Welcome to Socka | Add a new player"
});
} else {
if (uploadedFile.mimetype === 'image/png' || uploadedFile.mimetype === 'image/jpeg' || uploadedFile.mimetype === 'image/gif') {
uploadedFile.mv(`public/assets/img/${image_name}`, (err ) => {
if (err) {
return res.status(500).send(err);
}
// send the player's details to the database
let query = "INSERT INTO `players` (first_name, last_name, position, number, image, user_name) VALUES ('" +
first_name + "', '" + last_name + "', '" + position + "', '" + number + "', '" + image_name + "', '" + username + "')";
db.query(query, (err, result) => {
if (err) {
return res.status(500).send(err);
}
res.redirect('/');
});
res.redirect('/');
});
});
} else {
message = "Invalid File format. Only 'gif', 'jpeg' and 'png' images are allowed.";
res.render('add-player.ejs', {
message,
title: "Welcome to Socka | Add a new player"
});
}
}
});
}

Node JS for loop inserting data twice

I am trying import the contacts in a database but sometime its inserting records 2 times. Requirement is, If the number is already exist it should get updated otherwise inserted as a new row. I am using MySQL database.
I am using for loop with async.
var numbers = {
numbers:[
{
name:"A",
number:9876543211
},
{
name:"B",
number:7876543211
},
{
name:"C",
number:9886543211
},
{
name:"D",
number:8876543211
}
]
};
async.forEachOf(numbers, (numberObj, key, callback) => {
var createdAt = moment.utc().valueOf();
var updatedAt = moment.utc().valueOf();
gfs.checkContact(userInfo.user_id, code, numberObj.number, function(contactInfo, err){
if(err){
response.error = "sorry";
res.send(response); return false;
}else{
if (contactInfo.length > 0) {
gfs.qry("UPDATE contacts SET fullName='"+numberObj.name+"', updatedAt='"+updatedAt+"' WHERE cid='"+contactInfo[0].cid+"'").then(function (results){
}).catch(function (errorMessage){
})
}else{
gfs.qry("INSERT INTO contacts(user_id, fullName, code, mobile, createdAt, updatedAt) VALUES('"+userInfo.user_id+"', '"+numberObj.name+"', '"+code+"', '"+numberObj.number+"', '"+createdAt+"', '"+updatedAt+"')").then(function (results){
}).catch(function (errorMessage){
})
}
}
callback();
});
}, err => {
if (err){
response.error = "sorry";
res.send(response);
}else{
response.success = "success";
response.numbers = numbers;
res.send(response);
}
});
I want to insert the contact number if it's not exist in the database for logged-in user id or it should get update the other fields like name, updated at if number already in database for the logged-in user id.
The callback needs to be inside the .thens or .catches.
async.forEachOf(numbers, (numberObj, key, callback) => {
var createdAt = moment.utc().valueOf();
var updatedAt = moment.utc().valueOf();
gfs.checkContact(userInfo.user_id, code, numberObj.number, function (contactInfo, err) {
if (err) {
return callback(err);
} else {
if (contactInfo.length > 0) {
gfs.qry("UPDATE contacts SET fullName='" + numberObj.name + "', updatedAt='" + updatedAt + "' WHERE cid='" + contactInfo[0].cid + "'")
.then(function (results) {
return callback(null, true);
}).catch(function (errorMessage) {
return callback(errorMessage);
})
} else {
gfs.qry("INSERT INTO contacts(user_id, fullName, code, mobile, createdAt, updatedAt) VALUES('" + userInfo.user_id + "', '" + numberObj.name + "', '" + code + "', '" + numberObj.number + "', '" + createdAt + "', '" + updatedAt + "')")
.then(function (results) {
return callback(null, true);
}).catch(function (errorMessage) {
return callback(errorMessage);
})
}
}
});
}, err => {
if (err) {
response.error = "sorry";
res.send(response);
} else {
response.success = "success";
response.numbers = numbers;
res.send(response);
}
});
Note: in your function gfs.checkContact the callback signature is (contactInfo, err). Which is reverse of what Node.js standard. Node uses err, callback or err, data.
EDIT1:
Also, .forEachOf iterates object like Object.keys. In your case there is only one key called numbers.
So, the numberObj will contain:
[ { name: 'A', number: 9876543211 },
{ name: 'B', number: 7876543211 },
{ name: 'C', number: 9886543211 },
{ name: 'D', number: 8876543211 } ]
And numberObj.name will be undefined.
You probably want
async.each(numbers.numbers, ...)
I have changed my code, now using promise. It's working fine now.
var numbers = [
{
name:"A",
number:9876543211
},
{
name:"B",
number:7876543211
},
{
name:"C",
number:9886543211
},
{
name:"D",
number:8876543211
}
];
async.forEachOf(numbers, (numberObj, key, callback) => {
var createdAt = moment.utc().valueOf();
var updatedAt = moment.utc().valueOf();
gfs.checkContactPromise({
user_id:userInfo.user_id,
code:code,
mobile:numberObj.number,
fullName:numberObj.name,
createdAt:createdAt,
updatedAt:updatedAt
}).then( function (addContactQry){
gfs.qry(addContactQry).then(function (results){
userContacts.push("'"+numberObj.number+"'");
callback();
}).catch(function (errorMessage){
callback();
})
}).catch( function (errorMessage){
callback();
});
}, err => {
if (err){
response.error = "sorry";
res.send(response);
}else{
response.success = "success";
response.numbers = numbers;
res.send(response);
}
});

Waiting query result

I can't succeed into waiting an sql query result
This is what my Code looks like
socket.on('new', async function(information) {
console.log("check no offer en cours");
var checkOffer = "SELECT COUNT(*) as total FROM app__offer WHERE status_id = 1 AND profile_id = " + user.idUser;
doInsert = false;
con.query(checkOffer, function(err, result) {
if (err) throw err;
console.log(result[0].total);
if (result[0].total == 0) {
console.log("can insert");
doInsert = true;
}
}).then(function() {
console.log(doInsert);
if (doInsert) {
console.log("create offer");
var sql = "INSERT INTO app__offer (createdAt,updatedAt, startAt, programmed, startLatitude, startLongitude, commune_id, point_id, status_id,device,profile_id) " +
"VALUES ('" + todayDateTime + "','" + todayDateTime + "','" + todayDateTime + "'," + false + "," + user.latitude + "," + user.longitude + "," + user.idCommuneDestination + "," + user.idPoint + "," + 1 + "," + 'device' + "," + user.idUser + ")";
console.log(sql);
con.query(sql, function(err, result) {
if (err) throw err;
socket.emit('new', result);
});
} else {
console.log("Cet user a déjà une offre en cours");
}
});
Issue is the doInsert Log is executed before the canInsert Log.
I think that con.query() accept the callback and is also "thennable" returning a Promise.
In most cases if the callback is provided, that will be the handler of the result and it wont be passed to the Promise.
So
con.query(query, () => {
// this code is executed when the query ends
}).then(() => {
// this code is executed when the promise attached to .then() is resolved
// in this case con.query() is instant resolved cause a callback parameter is given
})
The solution is to put all in the callback OR all in the promise chain.
I would do like :-
try{
let result = await con.query(checkOffer);
if (result) {
let resultFromAnotherQuery = await con.query(sql);
if (resultFromAnotherQuery){
console.log("done");
}
}
}catch(err) {
console.log(err);
}

How to redirect to a different ejs file in the same folder in node.js

Whenever I'm trying to redirect my node.js file (form.js) to the same page using res.redirect("/"); it is working!
But when I'm trying to redirect to a different file(welcome.ejs) in the same folder using res.redirect("/welcome"); it is not working.
My welcome.ejs file has this sentence in it <h1>Welcome Home</h1> and that's it.
My mysql database is working just fine and I can see the message "rows affected". So I'm pretty sure there is no issue there.
I'm not even getting any errors.
I cannot understand why I cannot redirect to welcome.ejs page but I can redirect to home page(home.ejs or "/"). In the browser the message says "cannot get /welcome"
I even tried return res.redirect(/welcome) or res.redirect("/welcome.ejs") but it didn't work!
my folder structure is views/home.ejs & views/welcome.ejs.
Can anyone please help me with this?
this is my form.js code
app.get('/accountform', function(req, res) {
var q = "SELECT COUNT(*) AS count FROM `Projects`";
connection.query(q, function(err, results){
if (err) throw err;
var count = results[0].count;
//res.send("We have " + count + " no of users.");
res.render("accountform", {count: count});
});
app.post('/addproject', function(req, res){
var project = {
Project_No: req.body.Project_No,
Project_Name: req.body.Project_Name,
Status: req.body.Status,
Project_Type: req.body.Project_Type
};
connection.query('insert into `Projects` SET ?', project, function(err,
result){
console.log(err);
console.log(result);
res.redirect("/welcome");
});
});
});
I try something near to your code
this is my app.js
const {getHomePage} = require('./routes/index');
const {addPlayer} = require('./routes/player');
app.get('/', getHomePage);
app.post('/add', addPlayer);
routes/index.js
module.exports = {
getHomePage: (req, res) => {
let query = "SELECT * FROM `players` ORDER BY id ASC";
db.query(query, (err, result) => {
if (err) {
res.redirect('/');
}
res.render('index.ejs', {
title: "Welcome to Socka | View Players"
,players: result
});
});
},
};
routes/player.js
module.exports = {
addPlayerPage: (req, res) => {
res.render('add-player.ejs', {
title: "Welcome to Socka | Add a new player"
,message: ''
});
},
addPlayer: (req, res) => {
if (!req.files) {
return res.status(400).send("No files were uploaded.");
}
let message = '';
let first_name = req.body.first_name;
let last_name = req.body.last_name;
let position = req.body.position;
let number = req.body.number;
let username = req.body.username;
let uploadedFile = req.files.image;
let image_name = uploadedFile.name;
let fileExtension = uploadedFile.mimetype.split('/')[1];
image_name = username + '.' + fileExtension;
let usernameQuery = "SELECT * FROM `players` WHERE user_name = '" + username +
"'";
db.query(usernameQuery, (err, result) => {
if (err) {
return res.status(500).send(err);
}
if (result.length > 0) {
message = 'Username already exists';
res.render('add-player.ejs', {
message,
title: "Welcome to Socka | Add a new player"
});
} else {
if (uploadedFile.mimetype === 'image/png' || uploadedFile.mimetype ===
'image/jpeg' || uploadedFile.mimetype === 'image/gif') {
uploadedFile.mv(`public/assets/img/${image_name}`, (err ) => {
if (err) {
return res.status(500).send(err);
}
let query = "INSERT INTO `players` (first_name, last_name,
position, number, image, user_name) VALUES ('" +
first_name + "', '" + last_name + "', '" + position + "', '"
+ number + "', '" + image_name + "', '" + username + "')";
db.query(query, (err, result) => {
if (err) {
return res.status(500).send(err);
}
res.redirect('/');
});
});
} else {
message = "Invalid File format. Only 'gif', 'jpeg' and 'png' images
are allowed.";
res.render('add-player.ejs', {
message,
title: "Welcome to Socka | Add a new player"
});
}
}
});
}
}
i have index.ejs and addplayer.ejs in views folder
this is my full github code
https://github.com/gayathribrittany/nodeapp

Resources