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)
});
}
});
Related
I have this:
var id = req.body.id;
var query = {'_id': req.body.id, 'site': req.body.location, 'content': req.body.services, 'updatedByCNUM': req.body.cnum};
ServicesModel.findOneAndUpdate(query, id, {upsert: true}, function(err, doc) {
if (err) return res.send(500, {error: err});
return res.send('Succesfully saved.');
});
console.log(req.body.Services, req.body.location)
I am new to mongoose, and I am trying to do an update query. I basically have the ID of the document, so I want to find it, and then update it with the new values (all being based into query). How can I do this? This above is not working, it says :
TypeError: Cannot convert undefined or null to object
thanks 4 the help
ServicesModel.findOneAndUpdate(
{_id : req.body.id},
{ $set: { site: req.body.location, content: req.body.services, updatedByCNUM: req.body.cnum } },
, {upsert: true, new: true}, function(err, doc) {
if (err) return res.send(500, {error: err});
return res.send('Succesfully saved.');
});
var id = req.body.id;
var query = {'_id': req.body.id, 'site': req.body.location, 'content': req.body.services, 'updatedByCNUM': req.body.cnum};
ServicesModel.findOneAndUpdate(
{_id : req.body.id},
{ $set: { query} },
function(err, doc) {
if (err) return res.send(500, {error: err});
return res.send('Succesfully saved.');
});
Note: $set replaced every data there before. to add a new data on the previous one you need to use $pull or $push. you can check the docs here
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");
}
});
});
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);
})
});
},
So I am trying to update the field status in my Report document and in my Station.reports sub-document which is an array of objects, in one single API call. The issue is that I am able to update the Report document, but not the station document when making the API call. After the call, the console.log(station.reports); returns the expected subdocument which is : [{"_id":"588fed278b50cd180bd6cc15","date":"2017-01-31T01:48:57.487Z","status":"Archived"}] But this is not saved in the corresponding Station document in my DB. Please I need help here. Thanks.
Station Document:
{
"_id": "588a777d4e26720e7afa7e1e",
"phone": "(007) – 007 – 7007",
"name": "name1",
"email": "name1#email.com",
"reports": [
{
"status": "Submitted",
"date": "2014-01-31T01:48:57.487Z",
"_id": "588fed278b50cd180bd6cc15"
}
]
}
Report Document
{
"_id": "588fed278b50cd180bd6cc15",
"description": "Description of the report",
"time": "05:48 PM",
"date": "2017-01-31T01:48:57.487Z",
"status": "Archived",
"location" : "123 Main Street"
"station" : "588a777d4e26720e7afa7e1e"
}
API Call
router.put('/reports/:id/updateStatus', function (req, res) {
Report.findById(req.params.id, function(err,report){
// if there is an error retrieving, send the error.
// nothing after res.send(err) will execute
if (err)
return res.send(err);
// Update the Report object
report.status = req.body.status;
// Update the Corresponding station.reports subdocument
Station.findOne({_id:report.station}, function (err, data) {
if(err) return console.log(err);
data.reports.forEach(function(rpt){
if (rpt._id == req.params.id){
rpt.status = req.body.status
data.save(function (err, station) {
if (err)
return res.send(err);
console.log(station.reports);
})
}
})
})
report.save(function (err, report) {
if (err)
return res.send(err);
res.json(report);
})
});
})
You are doing mistake while updating the station object. Use findOneAndUpdate to find the matching Station document, and then change the status of the matched reports item(matched using reports._id).
Try this:
Station.findOneAndUpdate({
_id:report.station,"reports._id":req.params.id
},{
$set : {reports.$.status : req.body.status}
},function(err){
if(err)
return res.send(err);
});
report._id will find the array element whose _id is req.params.id and report.$.status will update only the matching element of the array.
For more information on positional $(update) operator, Read mongoDB positional Documentation.
Also, i would suggest to save the report object in the callback of update. As nodejs is asynchronous, it will not wait for the update to finish, if you are saving report outside of the callback. And, you might get Cant set the headers after they are sent error. Thus, its recommended to do it in the callback.
Thus your final API code would look like:
router.put('/reports/:id/updateStatus', function (req, res) {
Report.findById(req.params.id, function(err,report){
// if there is an error retrieving, send the error.
// nothing after res.send(err) will execute
if (err)
return res.send(err);
// Update the Report object
report.status = req.body.status;
// Update the Corresponding station.reports subdocument
Station.findOneAndUpdate({
"_id":report.station,"reports._id":req.params.id
},{
$set : {"reports.$.status" : req.body.status}
},function(err, result){
if(err)
return res.send(err);
console.log(result);
report.save(function (err, report) {
if (err)
return res.send(err);
res.json(report);
});
});
});
})
UPDATE
Alternate Method
Another way can be, You can proceed in the original way, but don't save the data inside the forEach, instead save the data sheet forEach finishes.
Station.findOne({_id:report.station}, function (err, data) {
if(err) return console.log(err);
data.reports.forEach(function(rpt){
if (rpt._id == req.params.id){
rpt.status = req.body.status
}
});
data.save(function (err, station) {
if (err)
return res.send(err);
console.log(station.reports);
report.save(function (err, report) {
if (err)
return res.send(err);
res.json(report);
});
})
})
Hope this helps!
After multiple attempts, and with the help of Ravi, I was able to figure out a solution that worked for me pretty well. The only thing that changed was my API call. The rest of the code was unchanged.
Hope this helps someone having similar needs.
API CALL
router.put('/reports/:id/updateStatus', function (req, res) {
Report.findById(req.params.id, function(err,report){
// if there is an error retrieving, send the error.
// nothing after res.send(err) will execute
if (err)
return res.send(err);
// Update the Report object
report.status = req.body.status;
// Update the Corresponding station.reports subdocument
Station.findOne({_id:report.station}, function (err, info) {
if(err) return console.log(err);
info.reports.forEach(function(rpt){
if (rpt._id == req.params.id){
Station.update({_id:info._id, "reports._id":rpt._id },
{
$set:{"reports.$.status": req.body.status }
},function (err, results) {
if(err) return console.log("This Station couldn't be updated " + err);
console.log(results)
}
)
}
})
report.save(function (err, report) {
if (err)
return res.send(err);
res.json({report:report, station:info});
});
})
});
})
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);
}
});