How to Save data in multiple Collection using Mongodb and node js - javascript

I am using nodeJS and mongodb in one of my project.
I am trying to save data in multiple collection in one save button.
The code which I am using to achieve this is as follow:
var lastInsertId;
loginData={
userName: req.body.txtUsername,
password: req.body.txtPassword,
active:1,
createdOn:new Date(),
updatedOn:new Date()
};
var dbo = db.db("test");
dbo.collection("login").insertOne(loginData, function(err, result) {
if (err) throw err;
lastInsertId=result.insertedId;
});
if(lastInsertId){
usersData={
email: req.body.txtEmail,
firstName: req.body.txtFirstName,
lastName:req.body.txtLastName,
mobileNumber:req.body.txtMobileNumber,
login_id:lastInsertId,
active:1,
createdOn:new Date(),
updatedOn:new Date()
};
dbo.collection("users").insertOne(usersData, function(err, result) {
if (err) throw err;
console.log('saved to users');
});
}
Could you please tell what is wrong in the above code?
Thank you.
Regards,
Saloni

I want to give an explanation regarding the above issue with the code.
var lastInsertId; //it is undefined right now
//The following function is an asynchronous function.
var dbo = db.db("test");
dbo.collection("login").insertOne(loginData, function(err, result) {
if (err) throw err;
lastInsertId=result.insertedId;
});
/*NodeJs doesn't run synchronously. So, while it is running
above function i.e. insertOne, without it being completed it
reaches here.
Since, the above function is not completed
executing, lastInsertId will be undefined still.
So, the following block of code doesn't run */
if(lastInsertId){ //this block won't run
usersData={
//key-value pairs
};
dbo.collection("users").insertOne(usersData, function(err, result) {
if (err) throw err;
console.log('saved to users');
});
}
/*The solution to the above problem can be achieved by putting the
code block inside 'if(lastInsertId)' in callback of insert login.
So it would run only after the execution of insertOne function.*/
//Therefore the correct code would be:
var dbo = db.db("test");
dbo.collection("login").insertOne(loginData, function(err, result) {
if (err) throw err;
lastInsertId=result.insertedId;
if(lastInsertId){ //this block will run
usersData={
//key-value pairs
};
dbo.collection("users").insertOne(usersData, function(err, result) {
if (err) throw err;
console.log('saved to users');
});
}
});

I think move IF block inside callback of insert login function like this should work
var lastInsertId;
loginData = {
userName: req.body.txtUsername,
password: req.body.txtPassword,
active: 1,
createdOn: new Date(),
updatedOn: new Date()
};
var dbo = db.db("test");
dbo.collection("login").insertOne(loginData, function (err, result) {
if (err) throw err;
lastInsertId = result.insertedId;
if (lastInsertId) {
usersData = {
email: req.body.txtEmail,
firstName: req.body.txtFirstName,
lastName: req.body.txtLastName,
mobileNumber: req.body.txtMobileNumber,
login_id: lastInsertId,
active: 1,
createdOn: new Date(),
updatedOn: new Date()
};
dbo.collection("users").insertOne(usersData, function (err, result) {
if (err) throw err;
console.log('saved to users');
});
}
});

Related

how to get the new value of document after updating each time in nodejs loop?

I'm trying to update collection many times in a loop but each time I get the value of oldRight not changed it gives the first value always.
I'm storing topics in mongodb using nested sets pattern.
for(let name of level1) {
console.log(name);
var parent = 'root';
getParentAndAddTopic(name, parent, function (err, topic) {
if (err) {
console.log(err);
}
var oldRight = topic.right;
console.log(oldRight);
db.topics.create({name: name, parent: 'root', left: oldRight, right: oldRight + 1}
, function (err, res) {
if (err) throw err;
});
db.topics.updateMany({right: {$gte: oldRight}}, {$inc: {right: 2}}
, function (err, res) {
if (err) throw err;
});
});
function getParentAndAddTopic(name, parent, callback) {
db.topics.find({name: 'root'}, function (err, topics) {
if (err) {
callback(err, null);
} else {
callback(null, topics[0]);
}
});
}
}
Working with the database is an asynchronous function, you can't do it in a normal loop. And change var to let, using var is a bad practice leading to many problems.

why mongodb in node express cannot set result to outside variable

So this question might be a javascript concept question. but I cannot figure out why
I retrieve data from mongodb however, I cannot define _res variable to become the result.
console.log(_res) will return undefined.
Does anyone know why? and how to make it work as it should be?
app.route('/').get(function(req,res){
let _res;
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("vm");
var query = {};
dbo.collection("vm").find(query).toArray( function(err, result) {
if (err) throw err;
var vmData = JSON.stringify (result)
_res = vmData
db.close();
res.render('index.ejs', {
vmData: vmData
});
});
});
console.log(_res)
});
Mongodb query is an asynchronous operation. The console statement is executed before the query has been processed.
You define _res outside which is undefined outside, so the same value is consoled outside.
app.route('/').get(function(req,res){
let _res;
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("vm");
var query = {};
dbo.collection("vm")
.find(query)
.toArray((err, result){
if (err) throw err;
var vmData = JSON.stringify (result)
_res = vmData
db.close();
console.log('Inside', _res) // <---Should give you correct result
res.render('index.ejs', {
vmData: vmData
});
});
});
console.log('Outside', _res);
});
The code is being executed asynchronously due to which when the console.log is executed the _res is undefined.
Try to execute your logic when the asyn methods are being executed.
app.route('/').get(function(req,res){
let _res;
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("vm");
var query = {};
dbo.collection("vm").find(query).toArray( function(err, result) {
if (err) throw err;
var vmData = JSON.stringify (result)
_res = vmData;
console.log(_res);
db.close();
res.render('index.ejs', {
vmData: vmData
});
});
});
});

Mongodb find() return undefined

When ever I try to just use a simple find() for my mongodb it returns undefined.
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/local';
MongoClient.connect(url, function (err, db) {
db.collection('pokemon').find({ $search: { $text: 'Pikachu' } }).toArray(function(err, data){ console.log(data) })
});
EDIT:
Turns out I never created an index by putting
db.collection('pokemon').createIndex({Name: 'text'})
before all the code.
First of all, every time where you have:
function(err, data){ console.log(data) }
you should check errors:
function (err, data) {
if (err) {
console.log('Error:', err);
} else {
console.log('Data:', data);
}
}
Then you will probably see what's going on.
This is also true for the database connection itself - instead of:
MongoClient.connect(url, function (err, db) {
// use db here
});
you should handle errors:
MongoClient.connect(url, function (err, db) {
if (err) {
// handle errors
} else {
// use db here
}
});
If you don't handle errors then don't be surprised that you don't know why you don't get values.

How to wait for a response from a mongo findOne query in a node/express app before using the response in following control flow

I am new to node, and also JavaScript callbacks.
I am trying to check if an account exists in mongo and then 'save it' if it doesn't and return an error if it does.
I am currently trying to figure this out outside of my express app. This is what i have..
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/main', function (err, db) {
if(err) throw err;
var query = { name : "www.website.com"}
findOne(db, query, function (doc) {
if(doc) {
console.log('account exists');
} else {
console.log('good to go');
}
console.dir(doc);
});
});
var findOne = function (db, query, callback) {
db.collection('accounts').findOne(query, function (err, doc) {
if(err) throw err;
db.close();
callback();
});
}
with the console.dir(doc); above returning as undefined. How do I wait for the findOne to return before using the callback to console.log or save the account?
The reason you are getting undefined is because when you call your callback your are not passing it the doc. That line should look like callback(doc).
Here is an updated version of your code with a few suggestions:
MongoClient.connect('mongodb://localhost:27017/main', function (err, db) {
if(err) throw err;
var query = { name : "www.website.com"}
findOne(db, query, function (err, doc) {
if(err) {
// something went wrong
console.log(err);
return;
}
if(doc) {
console.log('account exists');
console.dir(doc);
} else {
console.log('good to go');
}
});
});
var findOne = function (db, query, callback) {
db.collection('accounts').findOne(query, function (err, doc) {
db.close();
if(err) {
// don't use throw when in async code
// the convention is to call your callback with the error
// as the first argument (notice that I added an argument
// to the definition of your callback above)
callback(err);
}
else {
// call your callback with no error and the data
callback(null, doc);
}
});
}

making the output of "find" using mongodb with nodejs look better

I am using a function to find clients from my mongodb database using node js.
In my query I'm trying to get the function to output the data without the "_id"
but it's not working.
function findClient(Fname,res){
let query = {name:Fname}
dbo.collection("clients")
.find(query,{ _id: 0,name: 1 ,last: 1, age:1})
.toArray(function(err, result) {
if (err) throw err;
result = JSON.stringify(result)
res.render(`./pages/findRes`,{data:result})
console.log(result)
});
}
You don't need to use toArray here.
function findClient(Fname, res) {
let query = { name: Fname }
dbo.collection("clients").find(query, { _id: 0, name: 1, last: 1, age: 1 }, function (err, result) {
if (err) throw err;
result = JSON.stringify(result)
res.render(`./pages/findRes`, { data: result })
console.log(result)
});
}
Basic example here: https://mongoplayground.net/p/WzCaITFhCHM
This should work.

Categories

Resources