Reputation: 8503
I am developing a mongoose / node.js / express app.
in my routes I am using express' app.param() method to get my model instance into the request - instead of fetching it in each controller action.
i got show
and create
actions working in my controller - however I am stuck implementing the update
action.
here is my relevant controller code:
// mymodel-controller.js
var mongoose = require('mongoose')
var MyModel = mongoose.model('MyModel');
var utils = require('../../lib/utils');
"use strict";
exports.update = function (req, res, next) {
var mymodel = req.mymodel;
mymodel.set(req.body);
mymodel.slug = utils.convertToSlug(req.body.title);
mymodel.save(function(err, doc) {
if (!err) {
console.log('update successful');
// here i see the correctly updated model in the console, however the db is not updated
console.dir(doc);
return res.redirect('/mymodels/' + mymodel.slug);
} else {
console.error('update error', err);
return res.render('mymodels/edit', {
title: 'Edit Model',
model: mymodel,
errors: err.errors
});
}
});
}
The strange thing is, the mongoose save goes through successfully, I don't get any error. I see 'update successful' and the correctly updated model printed on the console, but not persisted in the database. I tried also fetching the model manually before updating and saving it, instead of using app.param(..) but I had the same effect. Any idea what I am missing here?
update
this is the code where I set the req.mymodel
- part of a longer routes file.
In my show actions e.g. I also use req.mymodel to display it and it works fine so far.
/**
* mymodel ROUTES
*/
app.param('mymodel', function(req, res, next, id){
MyModel.findOne({ 'slug': id }, function(err, mymodel) {
if (err) {
next(err);
} else if (mymodel) {
req.mymodel = mymodel;
next();
} else {
res.status(404).render('404', {title: "Not found", errorMessage: "The requested mymodel was not found."});
}
});
});
app.get('/mymodels', mymodelsController.index);
app.get('/mymodels/new', mymodelsController.new);
app.post('/mymodels', mymodelsController.create);
app.get('/mymodels/:mymodel', mymodelsController.show);
app.get('/mymodels/:mymodel/edit', mymodelsController.edit);
app.put('/mymodels/:mymodel', mymodelsController.update); // that's the one not working with the code above
app.del('/mymodels/:mymodel', mymodelsController.destroy);
update2
This code, on the other hand, works in my controller and updates the database (I'd much prefer using instance.save() though)
exports.update = function (req, res, next) {
var mymodel = req.param('mymodel');
var query = { slug: mymodel };
var update = {};
update.title = req.param('title');
update.body = req.param('body');
update.points = req.param('points');
update.location = req.param('location');
update.slug = utils.convertToSlug(req.param('title'));
MyModel.update(query, update, function (err, numAffected) {
if (err) return next(err);
if (0 === numAffected) {
return next(new Error('no model to modify'), null);
}
res.redirect('/mymodels/' + update.slug);
});
}
Upvotes: 2
Views: 5529
Reputation: 8503
The problem was indeed the way I set the req.param
value in my routes.
Instead of doing this in my routes file:
app.param('mymodel', function(req, res, next, id){
MyModel.findOne({ 'slug': id }, function(err, mymodel) {
if (err) {
next(err);
} else if (mymodel) {
req.mymodel = mymodel;
next();
} else {
res.status(404).render('404', {title: "Not found", errorMessage: "The requested mymodel was not found."});
}
});
});
I had to declare a controller action that loads the instance each time, like
app.param('mymodel', mymodelController.load);
which pretty much looks like in this example.
Upvotes: 2