I am stuck trying to update MongoDB with added req.body.whatever data.
When I get the req.body data to my route, I can see it, change it and update to the database just fine, but when I add say, a new element into the req.body like so:
req.body.newData = "this is new";
In the route, it will not populate into MongoDB with the rest of the existing (changeable) req.body data that already exists in the DB document.
I can in code change an existing req.body.(KeyElement), and updates fine to the DB. Once I try to add an element to req.body, the new one just doesn't get updated. Tried all different update, modify, replaceOne etc and can get an editable result, but still no new elements being added to the database. I even tried the
Model.update(query, {$set: req.body}); etc
and this seems to update as well but nothing new gets added.
Here is the route I'm working with...
router.post('/set-repair-info', ensureAuthenticatedAdmin, function(req, res) {
console.log('set-repair-info : ');
var ObjectId = require('mongodb').ObjectID;
var b = req.body;
console.log('body: ');
console.log(req.body);
var repairToUpdate = req.body.jid;
// console.log(repairToUpdate);
// console.log('req.body[uid]');
// console.log(req.body.jid);
// console.log('userid::: ' + req.body.userid);
// console.log('backuped : ' + req.body.backedup);
// console.log(req.body.username);
//buggy without this;
if (req.body.backedup=='false'){
req.body.backedup == '';
}
//CHECKS AND RESPONSES:
//by Edit
//PARTS ORDERED
if(req.body.repairstatus == 'Parts Ordered'){
req.body.partsordered = 'true'; //THIS WILL NOT GO INTO DB!
} else{
req.body.partsordered = null;
}
req.body.testthisout = "THIS IS A TEST"; //THIS WILL NOT GO INTO DB!
console.log("parts: " + req.body.partsordered);
// Job.replaceOne({ _id: ObjectId(req.body.jid)}, req.body , {upsert: true}, function (err, result) {
// (err === null) ? {msg: 'something happened... err edit user'} : {msg: err}
// });
console.log('body updated: ');
console.log(req.body);
req.body.repairstatus = "Waiting For Something Else"; // UPDATES FINE
Job.update({ _id: ObjectId(req.body.jid)}, { $set: req.body }, function (err, result) {
(err === null) ? {msg: 'something happened... err edit user'} : {msg: err}
});
req.flash('success_msg','Repair has successfully been edited and saved to the database.');
res.render('edit-repair', { job: {'data': req.body} });
});
Double check your Models Schema and make sure variable is setup there.
Check your routes that create an instance of the Schema, make sure value is in there. And .save() or update through mongoose method.
SAVE the file.
Related
This is my first project with nodejs, and probably I am asking something trivial.
I hava a table to display list of items, that can be filtered in between two date.
The table has a link to edit and a form button to delete.
When I click to edit a line, I move to the editing page, I perform my actions and when I go back to the filtered page this is reloaded.
I follow answer 2 of this question, how to force page refresh on browser back click?
My problem is that I cannot achieve the same result with the delete form.
I tried res.redirect('back'); and res.redirect(req.get('referer'));
Can I be pointed to the right direction ?
Thanks Alb
app.search('/search', function(req, res) {
var sdate = req.body.sdate
var edate = req.body.edate
var sdate_full = req.body.sdate+' 00:00:00'
var edate_full = req.body.edate+' 24:59:59'
console.log("post received: %s %s", sdate, edate);
console.log("post received: %s %s", sdate_full, edate_full);
req.getConnection(function(error, conn) {
conn.query("SELECT * FROM item WHERE item_INSERT_DATE >= ? AND item_INSERT_DATE <= ?", [sdate_full, edate_full], function(err, rows) {
if (err) {
req.flash('error', err)
res.render('user/list', {
moment: moment,
title: 'Items',
data: ''
})
} else {
res.render('user/list', {
moment: moment,
title: 'Items',
data: rows
})
}
})
})
})
app.delete('/delete/(:id)', function(req, res, next) {
var user = { item_ID: req.params.id }
req.getConnection(function(error, conn) {
conn.query('DELETE FROM table WHERE item_ID = ' + req.params.id, user, function(err, result) {
if (err) {
req.flash('error', err)
res.redirect('/')
} else {
req.flash('success', 'Item deleted ! id = ' + req.params.id)
res.redirect(??????)
}
})
})
})
The form I start from is '/search', which filter my table list. The problem is that I can only redirect to '/' (which gives me the entire list), but not the search page updated with the line deleted. This is the last tiny bit to end this little job.
the simplest thing you could do is, when you click in the delete button in the frontend, call
const desiredTimeInMilliSeconds = 100;
setTimeout(function() {
window.location = window.location;
}, desiredTimeInMilliSeconds)
What should I do to stop the post request from posting new object if the object already exists?
I have pasted my code and json object. I have tried next(); but it doesnt work and a duplicate object with some other id is created no matter what. I am using before beforePostTransaction function to check if the product already exists. The request contains the id and the store id of the
index.js
const Transaction = require('./transactions/TransactionModel');
const TransactionCTL = require('./transactions/TransactionController');
Transaction.before('post', TransactionCTL.beforePostTransaction);
Transaction.register(router, '/transactions');
TransactionController.js
const beforePostTransaction = (req, res, next) => {
var id = req.body.id;
Transaction.findById(
id,
(err, data)=>{
if (!data){
next();
}
else{
var store = data.store;
store = JSON.stringify(store);
store = store.replace(/\"/g, "");
if(store !== req.body.store){ //update the whole object
next();
}
else{
//do what?
}
}
});
res.sendStatus(409);
}
json object
[{
"_id": "596db06849822a13c97ba3f9",
"store": "596b088131ea400490897c50"
}]
Not sure what is your model. But if it is mongoose you can use method
.findOneAndUpdate(query,
update,
{upsert: true},
function (error, result) {
if (!error) { //if you need to do something else
}
});
Where update is your object. It will create new item if it not exist and update it if it exist.
Hello I'm stuck in my first callback "selectArticleByTitle(title, callback)", the terminal send "Cannot read property 'id' of undefined". I don't know how to force the first callback to finish this and launch the others.
router.get('/article/:title', function(req, res){
dataBase.selectArticleByTitle(req.params.title, function(db_titleERR, db_titleResults){
console.log(db_titleResults);
dataBase.selectArticle(db_titleResults[0].id, function(db_resultsArticleERR, db_resultsArticle) {
//Get id of the previous article
dataBase.previousArticle(db_titleResults[0].id, function(db_previousIdERR, db_previousId){
//Get id of the next article
dataBase.nextArticle(db_titleResults[0].id, function(db_nextIdERR, db_nextId){
//Get lastArticle
dataBase.lastArticle(function(db_lastArticleERR, db_lastArticle) {
});
});
});
});
});
});
});
exports.selectArticleByTitle = function(title, callback){
connection.query('select * from article where title=?', [title], function(err, row){
if(err)
callback(err, null);
else{
if(row){
callback(null, row);
}
}
});
}
Here the log
console.log(db_titleResults);
[ RowDataPacket {
id: 7,
genre: 'Sciences',
picture: 'xw',
source: 'xswx',
title: 'zzazzaz',
meta: 'azazadsq',
inputDate: 2017-04-15T10:00:00.000Z,
visitor: 0 } ]
[]
Thank you in advance
If you want to stick with the original code then try the below...
The issue is that you are being returned one row. However you are trying to access the result as if there are many rows being returned in an array.
The below should at least get rid of your error. I would recommend to check the length of the results as well. if db_titleResults.length is defined then you know sql returned an array.
Instead of db_titleResults[0].id, you should use db_titleResults.id.
router.get('/article/:title', function(req, res){
dataBase.selectArticleByTitle(req.params.title, function(db_titleERR, db_titleResults){
console.log(db_titleResults);
dataBase.selectArticle(db_titleResults.id, function(db_resultsArticleERR, db_resultsArticle) {
//Get id of the previous article
dataBase.previousArticle(db_titleResults.id, function(db_previousIdERR, db_previousId){
//Get id of the next article
dataBase.nextArticle(db_titleResults.id, function(db_nextIdERR, db_nextId){
//Get lastArticle
dataBase.lastArticle(function(db_lastArticleERR, db_lastArticle) {
});
});
});
});
});
});
});
I am not sure what library you are using to connect to sql but can avoid nested call backs with an approach like below:
const sql = require('mssql')
sql.connect(config, err => {
// ... error checks
const request = new sql.Request()
request.stream = true // You can set streaming differently for each request
request.query('select * from article where title=?', [title])
request.on('row', row => {
// Emitted for each row in a recordset
dataBase.selectArticle(row.id, ...);
dataBase.previousArticle(row.id, ...);
dataBase.lastArticle(row.id, ...);
});
request.on('error', err => {
// May be emitted multiple times
});
});
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){
})
}
})
{ text: undefined,
done: false,
_id: 529e16025f5222dc36000002,
__v: 0 }
PUT /api/todos/529e16025f5222dc36000002 200 142ms - 68b
I keep getting this error when trying to do an update for my simple CRUD todo list. When I submit the update, the change doesn't appear on screen, although the put says it's a 200. Not sure what steps to take so that I don't get this "undefined" error and so I can have the update show up on screen.
EDIT: Included more code
This is the back-end node code:
app.put('/api/todos/:_id', function(req, res) {
Todo.findById(req.params._id, function(err, todos){
todos.text = req.body.text;
console.log(todos);
todos.save(function() {
if (!err) {
res.send(todos);
} else if (err) {
res.send(err);
}
Todo.find(function(err, todos) {
if (err)
res.send(err);
res.json(todos);
});
});
});
});
This is the Angular front-end code:
$scope.updateTodo = function(id) {
$scope.newItem = prompt("Please enter your new item:", "");
$http.put('/api/todos/' + id, {formData: $scope.newItem}).success(function(data) {
$scope.todos = data;
});
$http.get('/api/todos').success(function(data) {
$scope.todos = data;
});
};
I think it's because of this:
$http.put('/api/todos/' + id, { formData: $scope.newItem} )
^^^^^^^^
You're passing a single formData parameter with the request, yet in your Express code, you use this:
req.body.text
Either try this:
req.body.formData.text
Or don't use the formData parameter at all and pass $scope.newItem directly.
Besides that, your Express code is a bit messy: it might send back multiple responses and it doesn't check for errors on the save (as #PaulGray also pointed out).