简体   繁体   中英

Nodejs - Express - Mongoose: PUT Request problems with save method

Node shows me this error when I make a PUT request:

TypeError: product.save is not a function

(referring to the save function in controllers/product.js )

I find this is the right form to update a document, but I have this problem.

I'm sharing part of the code:

app.js

var api = express.Router();

api.route('/products') 
 .get(ProductCtrl.findAll)
 .post(ProductCtrl.add);

api.route('/products/:isbn')
 .get(ProductCtrl.findByISBN)
 .delete(ProductCtrl.delete)
 .put(ProductCtrl.update);

app.use('/api', api);

models/product.js

var mongoose = require('mongoose');
var Schema = mongoose.schema;

var productSchema = mongoose.Schema({
  isbn: {type: String},
  title: {type: String},
  author: {type: String},
  template: {type: String},
  active: {type: Number} //1 - Active, 0 - Inactive
});

module.exports = mongoose.model('Product', productSchema);

controllers/product.js

//PUT - Update the product by ISBN
exports.update = function(req, res){

Product.find(req.params.isbn, function(err, product){
    if(!product) res.status(404).send({message: 'Product not exits'});
    console.log("PUT - /products/" + req.params.isbn);
    product.isbn = req.body.isbn;
    product.title = req.body.title;
    product.author = req.body.author;
    product.active = req.body.active;
    product.template = req.body.template;

    product.save(function(err){
        if(err) return res.send(500,err.message);
        console.log("Successfully updated: " + req.body.isbn);
        res.status(200).json(product);
    });
});
};

Its because Model.find returns an array of items, not a specific mongoose object. So either try Model.findOne or Model.findById(id,(err,data)={})

Then you can call the save function. Also there's another way, instead of two queries try one. Model.findOneAndUpdate()

Hope this helps.

Preferably, use mongoose findOneAndUpdate method for your update like this. It looks terse and cleaner this way.

exports.update = function(req, res){

  Product
    .findOneAndUpdate({ isbn: req.params.isbn }, req.body)
    .exec(function(err, product){
      if(err) return res.status(500).json({err: err.message}):
      res.json({product, message: 'Successfully updated'})
    });
};

Do this

Product.find(req.params.isbn, function(err, product){
    if(!product) res.status(404).send({message: 'Product not exits'});
    console.log("PUT - /products/" + req.params.isbn);
    product.isbn = req.body.isbn;
    product.title = req.body.title;
    product.author = req.body.author;
    product.active = req.body.active;
    product.template = req.body.template;

   let updateproduct = new Product(product);

    updateproduct.save(function(err){
        if(err) return res.send(500,err.message);
        console.log("Successfully updated: " + req.body.isbn);
        res.status(200).json(product);
    });
});
};

Please use this

exports.update = function(req, res){

    Product.find(req.params.isbn, function(err, product){
        if(!product) res.status(404).send({message: 'Product not exits'});
        console.log("PUT - /products/" + req.params.isbn);
        product.isbn = req.body.isbn;
        product.title = req.body.title;
        product.author = req.body.author;
        product.active = req.body.active;
        product.template = req.body.template;

        Product.save(product,function(err,data){
            if(err) return res.send(500,err.message);
            console.log("Successfully updated: " + req.body.isbn);
            res.status(200).json(product);
        });
    });
    };

instead of

    exports.update = function(req, res){

    Product.find(req.params.isbn, function(err, product){
        if(!product) res.status(404).send({message: 'Product not exits'});
        console.log("PUT - /products/" + req.params.isbn);
        product.isbn = req.body.isbn;
        product.title = req.body.title;
        product.author = req.body.author;
        product.active = req.body.active;
        product.template = req.body.template;

        product.save(function(err){
            if(err) return res.send(500,err.message);
            console.log("Successfully updated: " + req.body.isbn);
            res.status(200).json(product);
        }

);
});
};

That means you need to use product as Product .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM