How to update elements with array by its index in node js - javascript

I want to update element by its index number. I have data on Mongodb node.js like this:
{"_id" : ObjectId("5b533c33327d12098277c6a4"),
"name":["aa","bb","cc"],
"age":["45","50","40"],
"home":["dd","ee","ff"]}
I want to change the value of each element of name, age and home. I tried it like this, but it doesn't work.
router.put("/forms/data/edit/:index/:id", function(req,res){
var i = req.params.index;
Datastored.findByIdAndUpdate(req.params.id,{$set:{
name[i]:req.body.name,
age[i]:req.body.age,
home[i]:req.body.home}},
function(err){
if(err){
console.log(err)
res.redirect("back");
}else{
console.log("data edited");
res.redirect("/seealldata");
}
});
});
I get the following error:
parsing error: Unexpected token [ " , on the line of code, name[i].req.body.name

After a bit of googling, I found this question/answer.
Try the following:
router.put("/forms/data/edit/:index/:id", function(req,res){
var i = req.params.index;
Datastored.findByIdAndUpdate(req.params.id,{
$set:{
[`name.${i}`]: req.body.name,
[`age.${i}`]: req.body.age,
[`home.${i}`]: req.body.home
}},
function(err){
if(err){
console.log(err)
res.redirect("back");
}else{
console.log("data edited");
res.redirect("/seealldata");
}
});
});

You will need to construct the object like this first, {$set: {'field.2': value, ...}
router.put("/forms/data/edit/:index/:id", function(req,res){
var i = req.params.index;
var updateObj = { $set: {} };
updateObj.$set["name."+i] = req.body.name;
updateObj.$set["age."+i] = req.body.age;
updateObj.$set["home."+i] = req.body.home;
Datastored.findByIdAndUpdate(req.params.id, updateObj),
function(err){
if(err){
console.log(err)
res.redirect("back");
}else{
console.log("data edited");
res.redirect("/seealldata");
}
});
});

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);
})
});
},

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

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.

MEAN App - Updating table after DB Collection update

I 'm trying to keep my table data in sync with the db data.
On Data Change:
$scope.changeStatus = function($event,label,status){
var target = $event.currentTarget;
target = $(target).parents('tr').attr('id');
$http({
method: 'POST',
url: '/update',
params: {
trgt : target,
label : label,
labelstatus : status,
searchQuery : $scope.search
}
})
.success(function(data){
console.log(data);
$scope.events = data;
})
.error(
function(error){
console.log(error)
});
}
Then:
app.post('/update', function(req,res){
ImportCollection.findOne({ _id : req.query.trgt },function(err,doc){
doc.label.label = req.query.labelname;
doc.label.status = req.query.labelstatus;
doc.save();
});
// UNTIL HERE EVERYTHING WORKS JUST FINE
if(req.query.searchQuery){
ImportCollection.find({$or:[
{'localizedData.0.title' : {'$regex': req.query.searchQuery, $options: 'i' }},
{'licensor.name' : {'$regex': req.query.searchQuery, $options: 'i'}}
]})
.exec(function(err, imports){
if(err) throw err
res.json(imports)
})
} else{
ImportCollection.find({},function(err, imports){
if(err) throw err
res.json(imports)
})
}
});
But then the response that should update the table data, is allways one request behind.
So current Data = Live, I set it to QA and nothing happens. The table is still displaying Live. Once I change it now, lets say to DENIED, the table displays QA. I hope it's clearer now.
Does anyone have an idea?
Passing the find() block as a callback function to the doc.save() method worked for me:
doc.save(function(err){
if (err) throw error
var query = req.query.searchQuery;
if(query) {
ImportCollection.find({$or:[
{'localizedData.0.title' : {'$regex': req.query.searchQuery, $options: 'i' }},
{'licensor.name' : {'$regex': req.query.searchQuery, $options: 'i'}}
]}).exec(function(err, imports){
if(err) throw err
res.json(imports)
});
} else{
ImportCollection.find({}).exec(function(err, imports){
if(err) throw err
res.json(imports)
});
}
});

Mongo $addToSet with multiple values correct syntax

I have this mongoose schema:
var listingSchema = new Schema({
street : String,
buildingNumber : Number,
apartmentNumber : Number,
UsersAndQuestions: [{
userID: String,
questionID: [String]
}]
});
And I just want to update it with a new entry to UsersAndQuestions which will consist of a userID which is a String, and a questionID which is also a String (but needs to be inserted into an array).
I am using this PUT request:
app.put('/api/listing/:street/:buildingNumber/:apartmentNumber/addUserInput/:userid/:listingid/:questionid')
So I have all the necessary parameters in hand.
Usually, when I wanted to update a field in a schema I used this code that I wrote:
app.put('/api/listing/:street/:buildingNumber/:apartmentNumber/addReportedUser/:userid/:listingid', function (req, res) {
var listingToUpdate = req.params.listingid;
var idToAdd = req.params.userid;
Listing.update({_id: ObjectId(listingToUpdate)},
{$addToSet: {reportedUsersIDs: ObjectId(idToAdd)}}
, function (err) {
if (err) {
res.send("There was a problem adding the reportedUserID to the listing" + err);
}
else {
console.log("Success adding reportedUserID to listing!");
}
})
});
You can see I used $addToSet and it worked well. But now I want to add two parameters to a field which is an array. I thought about doing something like this:
app.put('/api/listing/:street/:buildingNumber/:apartmentNumber/addUserInput/:userid/:listingid/:questionid', function(req,res){
var listingToUpdate = req.params.listingid;
var idToAdd = req.params.userid;
var questionToAdd = req.params.questionid;
Listing.update({_id: ObjectId(listingToUpdate)},
{$addToSet: {UsersAndQuestions.userID : ObjectId(idToAdd), UsersAndQuestions.questionID : ObjectId(questionToAdd)}}
, function (err) {
if (err) {
res.send("There was a problem adding the user and question to the listing" + err);
}
else{
console.log("Success adding user and question to the listing!");
}
})
});
But I'm obviously getting a SyntaxError.
What is the correct syntax for doing what I tried to do?
Thanks a lot! :)
You need to add object to set UsersAndQuestions:
{$addToSet: {UsersAndQuestions: { userID: idToAdd, questionID: questionToAdd } }}
UPDATE.
I would do it with two queries:
Listing.update({_id: ObjectId(listingToUpdate), 'UsersAndQuestions.userID': idToAdd},
{"$addToSet": {"UsersAndQuestions.$.questionID": questionToAdd}}
, function (err, result) {
if(result.n === 0){
//we haven't found document with the userId - idToAdd
//we need to insert to UsersAndQuestions document with this user
Listing.update({_id: ObjectId(listingToUpdate)},
{$addToSet: {UsersAndQuestions: { userID: idToAdd, questionID: questionToAdd } }},
function(err, res){
})
}
})

Node.js & Mongoose, can't recover _id

I'm trying to save a document in my collection and if the save is successful, return the _id of this same document. The problem is I get an undefined value to my _id in both case, either the created model from mongoose or from the callback return. Basically, my only way of getting the _id would be to search the document by one of its properties, and then get the value. This approach isnt what I want, knowing what im currently trying to do should work.
var createTrophy = new Trophy({
name : post.name,
accessCode : post.password,
description : post.description,
members : [id]
});
Trophy.findOne({name:post.name}, function(err, trophy) {
if(err){
console.log('Mongoose: Error: ' + err);
res.send('Error db query -> ' + err);
}
else if(trophy){
console.log('Trophy ' + trophy.name + ' already existant');
res.send('Trophy ' + trophy.name + ' already existant');
}else{
createTrophy.save(function(err, doc){
var uid = createTrophy._id;
if (err) {
console.log('Error in trophy saving:' + err);
res.send('Error in trophy saving:' + err);
}else{
User.findOne({_id:post.id}, function(err, user) {
if(err){
console.log('Mongoose: Error: ' + err);
res.send('Error db query -> ' + err);
}
else if(user){
console.log(doc._id + ' ' + uid);
user.trophyLink = doc._id;
res.send(user);
//user.save(function(err){
// if(err){res.send('Couldnt update trophy of profile');}
//});
}
else{
console.log('User id Inexistant');
res.send('User id Inexistant');
}
});
}
});
}
});
});
The Schema
var Trophy = new Schema({
_id : ObjectId,
name : String,
accessCode : String,
description : String,
//reference to User ID
members : [Number],
comments :[Comment]
});
you don't have to supply _id in your Schema, it'll be generated automatically. and if you want the name to be unique you can also configure this in the Schema. if members are supposed to be "real" user _ids, than try sth like [ObjectId].
var TrophySchema = new Schema({
name: {type:String, required:true, unique:true},
accessCode: String,
description: String,
//reference to User ID
members: [ObjectId],
comments: [Comment]
});
and i don't know if this works
var trophy = new Trophy({...data...});
like you did it, i always do it like this:
var trophy = new Trophy();
trophy.name = "my name";
// ...
and the _id should be set as soon as you create the object (http://stackoverflow.com/questions/6074245/node-mongoose-get-last-inserted-id).
so just do it this way:
trophy.save(function (err) {
if (err) {
if (err.toString().indexOf('duplicate key error index') !== -1) {
// check for duplicate name error ...
}
else {
// other errors
}
res.send('Error in trophy saving:' + err);
}
else {
User.findOne({_id:post.id}, function(err2, user) {
if (err2) {/* ... */}
else if (user) {
user.trophyLink = trophy._id;
res.send(user);
}
}
}
});
important is, that save doesn't return the trophy you have to use the one you created yourself.

Categories