save() callback not being invoked on a mongoose schema object - javascript

Im trying to save a json object in my database. The save() function is not being called but and the json object is never saved.
Help me figure out the problem.
I guess it's a connection problem with mongoose.
Here is my code..
var config = require('../config');
var user = require('../user');
api.post('/addUser',function(req,res) {
var userID;
//creating a sample user under Model collection User.. so this becomes a document!!
console.log("addition of new user api hit!!");
//sending a query to retrieve the no of users served
MongoClient.connect(dbURL, function (err, db) {
var UserCountCursor = db.collection("ourusers").find({"docName": "userCount"}).limit(1);
UserCountCursor.each(function (err, doc) {
if (err)
console.log("did not get the count");
else
// var countString= JSON.stringify(doc);
//var docJson=JSON.parse(countString);
console.log("the json content is:" + doc.iparkoUserCount);
//increase the user count by 1 in the db.
var incCount = parseInt(doc.iparkoUserCount) + 1;
console.log("no of userrs:" + incCount);
// making an userId
userID = "ipkoID_C" + incCount.toString();
//updating using MOngoClient
db.collection("ourusers").update({"docName": "userCount"}, {$set: {"iparkoUserCount": incCount}});
console.log("the user count in the db has been updated!!");
console.log("generated id for this guy is:" + userID);
if (userID != null) {
console.log("calling the save function");
//closing the mongoclient connection
db.close();
signUpUser(userID);
}
});
});
function signUpUser(userIDD) {
var me = new user({
name: req.body.new_name,
password: req.body.new_pswd,
username: req.body.new_username,
phno: req.body.new_phn,
userId: userIDD
});
console.log("the obj ::" + JSON.stringify(me));
console.log("obj created and ready to be stored");
//connecting to the db using mongoose
mongoose.connect(config.database, function (err) {
if (err)
console.log("The error is :"+err);
else {
console.log("WE ARE CONNECTED USING MONGOOSE");
//saving the sample user document
me.save(function (err) {
console.log("in the save func");
if (err) throw err;
else {
console.log('User saved Successfully!!!!!');
res.json({
'whatStatus': 'user saved in the database!!',
'userID': userIDD
});
mongoose.connection.close();
}
});
}
});
}
});
My console logs::
addition of new user api hit!!
the json content is:143
no of userrs:144
the user count in the db has been updated!!
generated id for this guy is:ipkoID_C144
calling the save function
the obj ::{"name":"Abhi","password":"jio","username":"abhijio","phno":"45142545","userId":"ipkoID_C144","_id":"583295bfa0f9f8342035d3b9"}
obj created and ready to be stored
C:\Users\shivendra\WebstormProjects\iParko\node_modules\mongodb\lib\utils.js:98
process.nextTick(function() { throw err; });
^
TypeError: Cannot read property 'iparkoUserCount' of null
at C:\Users\shivendra\WebstormProjects\iParko\routes\RegisteredParkingLots.js:76:57
at handleCallback (C:\Users\shivendra\WebstormProjects\iParko\node_modules\mongodb\lib\utils.js:96:12)
at C:\Users\shivendra\WebstormProjects\iParko\node_modules\mongodb\lib\cursor.js:742:16
at handleCallback (C:\Users\shivendra\WebstormProjects\iParko\node_modules\mongodb\lib\utils.js:96:12)
at C:\Users\shivendra\WebstormProjects\iParko\node_modules\mongodb\lib\cursor.js:676:5
at handleCallback (C:\Users\shivendra\WebstormProjects\iParko\node_modules\mongodb\node_modules\mongodb-core\lib\cursor.js:156:5)
at setCursorDeadAndNotified (C:\Users\shivendra\WebstormProjects\iParko\node_modules\mongodb\node_modules\mongodb-core\lib\cursor.js:496:3)
at nextFunction (C:\Users\shivendra\WebstormProjects\iParko\node_modules\mongodb\node_modules\mongodb-core\lib\cursor.js:588:12)
at Cursor.next [as _next] (C:\Users\shivendra\WebstormProjects\iParko\node_modules\mongodb\node_modules\mongodb-core\lib\cursor.js:681:3)
at nextObject (C:\Users\shivendra\WebstormProjects\iParko\node_modules\mongodb\lib\cursor.js:673:8)
at Cursor.next (C:\Users\shivendra\WebstormProjects\iParko\node_modules\mongodb\lib\cursor.js:262:12)
at _each (C:\Users\shivendra\WebstormProjects\iParko\node_modules\mongodb\lib\cursor.js:738:10)
at C:\Users\shivendra\WebstormProjects\iParko\node_modules\mongodb\lib\cursor.js:746:7
at handleCallback (C:\Users\shivendra\WebstormProjects\iParko\node_modules\mongodb\lib\utils.js:96:12)
at C:\Users\shivendra\WebstormProjects\iParko\node_modules\mongodb\lib\cursor.js:676:5
at handleCallback (C:\Users\shivendra\WebstormProjects\iParko\node_modules\mongodb\node_modules\mongodb-core\lib\cursor.js:156:5)
Process finished with exit code 1

You seem to be opening the db connection twice one with mongoose.connect and another one with mongoose.connection.open(). That's why you are getting error.
Try using this with just one connection as below.
mongoose.connect(config.database, function(err, db) {
//var dbcon=mongoose.connection.open();
//dbcon.on('error',function(){console.log('connction error:')});
//dbcon.once('open',function(){
if(err) {
console.log(err);
} else {
console.log("WE ARE CONNECTED USING MONGOOSE");
//saving the sample user document
me.save(function (err) {
console.log("in the save func");
if (err) throw err;
else {
console.log('User saved Successfully!!!!!');
res.json({
'whatStatus': 'user saved in the database!!',
'userID': userIDD
});
//mongoose.connection.close();
}
});
}
});

Inside your UserCountCursor.each(...) loop, after checking for err you should also check for doc. So where you have this:
UserCountCursor.each(function (err, doc) {
if (err)
console.log("did not get the count");
else
// var countString= JSON.stringify(doc);
//...
})
do this instead:
UserCountCursor.each(function (err, doc) {
if (err){
console.log("did not get the count");
}else if(doc){
// var countString= JSON.stringify(doc);
//...
}
})
Then you will avoid the Cannot read property 'iparkoUserCount' of null error and you'll get into your save() function.

Related

Having issues editing an existing DB entry with Sails and Waterline

I'm using SailsJS as an API with Waterline connected to a MongoDB. I'm trying to put together an endpoint to edit existing DB entries but can't seem to get it to work and I'm hitting a wall as to why.
My route:
'post /edit/safety/:id': {
controller: 'SafetyController',
action: 'editSafety'
},
My controller function:
editSafety: function editSafety(req, res) {
var id = req.params.id;
Safety.findOneById(id).then((err, safety) => {
if (err) {
res.send(500, err);
return;
}
if (!safety) {
res.send(404, err);
return;
}
safety.title = req.body.title;
safety.description = req.body.description;
safety.status = req.body.status;
safety.save((err, updatedSafety) => {
if (err) {
re.send(500, err);
return;
}
res.send(200, updatedSafety);
});
});
},
Any push in the right direction would be greatly appreciated.
I don't recognize the Safety.findOneById method - is this something you have custom built? If not, then it is likely your problem.
Try swapping it for either:
Safety.findOne(id)
or
Safety.findOne({id: id})
Note that the returned object will be a model instance if the record exists, and undefined otherwise. If you decide to go with Safety.find instead then the returned value will be an array containing all models matching the query.
Looks like the main issue was transposing the response and err objects. It was successfully completing the query, but loading it into the err object which gets caught and a 500 error is thrown. So I changed that and simplified in a few other places.
editSafety: function editSafety(req, res) {
var id = req.params.id;
Safety.findOne(id).then((response, err) => {
var safety = response;
if (err) {
res.send(500, err);
return;
}
if (!response) {
res.send(404, err);
return;
}
safety.title = req.body.title;
safety.description = req.body.description;
safety.status = req.body.status;
Safety.update({
id: id
}, safety)
.then((result) => {
res.json(200, 'Ok!');
})
.catch((err) => {
sails.log.error('SafetyController.editSafety', err);
})
});
},

mongoose forEach loop and update documents one by one

I want to query a collection and update each document using some value that i will get from another query which is gonna be built with some info from the returned document.
const mongoose = require('mongoose');
const userModel = {
country: { type: String }
newField: { type: String }
};
const myUsersModel = mongoose.model('user',userModel);
myUsersModel.find({country:"USA"}).forEach(function (doc) {
// another query here into a relation Database:
let anotherQuery = 'SELECT * FROM myTable WHERE name=' + doc.name;
mySQLConnection.query(
anotherQuery,
function selectCb(err, results, fields) {
if (err) {
console.log("ERROR: " + err.message);
throw err;
}
console.log("Got "+results.length+" Rows:");
let updatedInfo = results.SomeField;
// update the mongoose doc:
doc.newField = updatedInfo;
myUsersModel.save(doc);
});
mySQLConnection.end(function(err) {
console.log("connection ended.");
});
mongoose.connection.close();
});
I am getting the following error:
TypeError: myUsersModel.find(...).forEach is not a function
myUsersModel.find({country:"USA"})
.then(users=>users.forEach //users might be null here btw
Or if you want to keep your callback style
myUsersModel.find({country:"USA"}, function(err, users) {
if (err) throw err;
users.forEach
If a callback is not provided, Model.find returns an instance of Query and not an instance of Array.
Hence, you can not use forEach as Query is not an Array.

in nodejs how to insert the record into PostgreSQL if it does not exist?

router.post('/university', function (req, res, next) {
pg.connect(connectionString,function(err,client,done) {
if(err){
console.log("not able to get connection "+ err);
res.status(400).send(err);
}
client.query("select university_name from university where university_name = '"+req.body.university_name+"'",function(err,data)
{
if(data) {
res.send({message:"exist"});
}
else
{
client.query("INSERT INTO university (_id, university_name, status) VALUES (nextval('university_id_seq'), '"+req.body.university_name+"', '"+req.body.status+"')", function(err, result) {
done();
if(err){
console.log(err);
res.status(400).send(err);
}
res.send({message : "successfully inserted"});
});
}
});
it displays university_name as exist even it is not present on every entry,
how to insert the record into PostgreSQL if does not exists?
It depends on which DB driver you are using, anyway most common is that when SELECT query is executed, you will get result data even if records in the DB doesn't exists. Usually result object then has property rows which you should check.
In your case similar to this:
if(data.rows && data.rows.length > 0){
// there is data in the DB
} else {
// no data in the DB
}

Validity of variable in node.js with sqlite3

I do a select statement on sqlite3 in node.js. I'd like to have the result in the variable "data" which is defined outside the sqlite code block but it stays empty. Within the sqlite code block the data variable has the correct value. Does anybody know what I'm doing wrong?
Thank you.
/* Client connects via socket.io */
io.on('connection', function(client) {
console.log('Client connected');
/* Client needs data... */
client.on('needData', function(fields) {
var data = [];
var sql_stmt = "SELECT ...";
if(fs.existsSync(db_file)) {
try {
var db = new sqlite3.Database(db_file);
db.all(sql_stmt, function(err, all) {
data = all;
console.log(data); //--> data has valid values
});
db.close();
console.log(data); //--> data is empty
}
catch(e) {
console.log("Error with database. Error: ", e);
}
}
else {
console.log("Database file not found.");
}
client.emit('data', data);
});
});
It happening just because of asynchronous nature of Node.js you can handle it with by promises
I recommend to use waterfall method of async module
var async=require('async');
/* Client connects via socket.io */
io.on('connection', function(client) {
console.log('Client connected');
/* Client needs data... */
client.on('needData', function(fields) {
async.waterfall([function(next) {
var sql_stmt = "SELECT ...";
if (fs.existsSync(db_file)) {
try {
var db = new sqlite3.Database(db_file);
db.all(sql_stmt, function(err, all) {
next(null,all)
});
db.close();
} catch (e) {
console.log("Error with database. Error: ", e);
next();
}
} else {
console.log("Database file not found.");
next();
}
}], function(err, data) {
if (!err) {
client.emit('data', data);
}
})
});
});

nodeJS + MSSQL, connection to db error: undefined is not a function

let's first see the code before I start talking:
var sqlDb = require("mssql");
var settings = require("../settings");
exports.executeSql = function (sql, callback) {
var conn = new sqlDb.Connection(settings.dbConfig);
console.log('db.js Send sql-query');
console.log(" ");
conn.connect()
.then(function () {
var req = new sqlDb.Request(conn);
req.query(sql)
.then(function (recordset) {
callback(recordset);
})
.catch(function (err) {
console.log("here it breaks", err);
callback(null, err); //type error: undefined is not a function
})
})
.catch(function (err) {
console.log(err);
callback(null, err);
}); //
};
This function recieves an sql statement and a callback function. When I run the code I get [Type Error: undefined is not a function].
When I comment out the callback(recordset) it doesnt do anything (no error but also nothing else). So I think that the callback is simply not recognized as if it were out of scope. The weird part is, that the error object is transferred back via the same callback function and that seems to work.
The settings.dbConfig looks like this:
exports.dbConfig = {
user: "username",
password: "pwd",
server: "SERVERNAME", // not localhost
database: "DB-Name",
port: 1433
};
I am quite depressed by now. Would someone be so kind as to have a look at my code? I simply don't see the mistake.
Thank you
EDIT:
I call executeSql like this:
var db = require("./db");
var sql = "SELECT * FROM myTable";
db.executeSql(sql, function(data, err) {
if (err) {
console.log(" Internal Error: error connecting Database", err);
} else {
console.log("success", data);
}
});

Categories