10

I've been writing my first node app, a rest api. I've got everything working pretty good but the PUT won't ever go through. I've tried lots of different combinations, lots of older tutorials and some new ones, and i'm probably pretty close I'm just not sure exactly how to update the record. Also, if you see anything that jumps out at you please feel free to let me know! I'm really liking node so I'd love to learn best practices.

Below is the route to my table, all of the other endpoints are working fine. let me know if you have any questions.

//Database
var mongoose = require("mongoose");
mongoose.connect('mongodb://Shans-MacBook-Pro.local/lantern/');


// Schema
var Schema = mongoose.Schema;  
var Person = new Schema({  
first_name: String,
last_name: String,
address: {
    unit: Number,
    address: String,
    zipcode: String,
    city: String,
    region: String,
    country: String
},
image: String, 
job_title: String,
created_at: { type: Date, default: Date.now },
active_until: { type: Date, default: null },
hourly_wage: Number,
store_id: Number,
employee_number: Number

});
var PersonModel = mongoose.model('Person', Person);  


// Return all people
exports.allPeople = function(req, res){
return PersonModel.find(function (err, person) {
  if (!err) {
    return res.send(person);
  } else {
    return res.send(err);
  }
});
}


// Create A Person
exports.createPerson = function(req, res){
var person = new PersonModel({
    first_name: req.body.first_name,
    last_name: req.body.last_name,
    address: {
        unit: req.body.address.unit,
        address: req.body.address.address,
        zipcode: req.body.address.zipcode,
        city: req.body.address.city,
        region: req.body.address.region,
        country: req.body.address.country
    },
    image: req.body.image,
    job_title: req.body.job_title,
    hourly_wage: req.body.hourly_wage,
    store_id: req.body.location,
    employee_number: req.body.employee_number
});

person.save(function (err) {
  if (!err) {
    return console.log("created");
  } else {
    return res.send(err);
  }
});

return res.send(person);
}


// Return person by id
exports.personById = function (req, res){
  return PersonModel.findById(req.params.id, function (err, person) {
if (!err) {
  return res.send(person);
} else {
  return res.send(err);
}
  });
}


// Delete a person by id
exports.deletePerson = function (req, res){
  return PersonModel.findById(req.params.id, function (err, person) {
return person.remove(function (err) {
  if (!err) {
    console.log("removed");
  } else {
    return res.send(err);
  }
});
  });
}


// Update a person by id
exports.updatePerson = function(req, res){
var person = new PersonModel({
    first_name: req.body.first_name
    });

    var upsertData = person.toObject();

    console.log(req.params.id); // OK

delete upsertData.id;

person.update({ _id: req.params.id }, upsertData, { multi: false }, function(err) {
    if(err) { throw err; }

    console.log('updated visit: '+ req.params.id);

    res.redirect('/');
});


}

My app.js

// Node Modules
var express     = require('express');
var app         = express();
app.port    = 3000;



// Routes
var people  = require('./routes/people');



// Node Configure
app.configure(function(){
  app.use(express.bodyParser());
  app.use(app.router);
});



// Start the server on port 3000
app.listen(app.port);



/*********
ENDPOINTS 
*********/

// People
app.get('/people', people.allPeople); // Return all people
app.get('/people/:id', people.personById); // Return person by id
app.post('/people', people.createPerson); // Create A Person
app.put('/people/:id', people.updatePerson); // Update a person by id, not working
app.delete('/people/:id', people.deletePerson); // Delete a person by id



// Logs
//  - Build some logs here for info when the server is going.
//  - routes that are loaded, any activity that might be helpful
console.log('Server started on port ' + app.port);

lastly, the json error on put

{
 "name": "MongoError",
 "err": "Mod on _id not allowed",
 "code": 10148,
 "n": 0,
 "connectionId": 91,
 "ok": 1
}
Shan Robertson
  • 2,742
  • 3
  • 25
  • 43
  • what is the log message for this bit? `var id = req.params.id; var person = req.body; console.log('Updating person: ' + id); console.log(JSON.stringify(person));` – KeepCalmAndCarryOn Sep 12 '13 at 03:49
  • Updating person: 522feac28edd8dcc05000001 for the first log and {"first_name":"Shan"} for the second. Thanks! – Shan Robertson Sep 12 '13 at 03:53
  • 1
    possibly this? http://stackoverflow.com/questions/17250496/update-a-record-where-id-id-with-mongoose – KeepCalmAndCarryOn Sep 12 '13 at 03:58
  • @KeepCalmAndCarryOn hey man, i tried to impliment that but to no avail.when trying to POST or PUT i would get "Cannot POST /people/522feac28edd8dcc05000001". How would I set up the model? I have a schema defined and setup as a model already.. Can I utilize that in my function? Thanks. – Shan Robertson Sep 12 '13 at 06:05

2 Answers2

12

Kept at it and finally figured it out! Here is my PUT function.

app.put('/people/:id', function (req, res) {
    var person = new PeopleModel({
        first_name: req.body.first_name,
        last_name: req.body.last_name,
                    // etc etc
    });

    var upsertData = person.toObject();

    delete upsertData._id;      

    return PeopleModel.update({ _id: req.params.id }, upsertData, {upsert: true}, function(err) {
          if (!err) {
              return res.send("updated");
          } else {
              console.log(err);
              return res.send(404, { error: "Person was not updated." });
          }
    });
});

I'm going to try and figure out how to auto detect what fields need to be updated, as just for testing i stored one var.

Shan Robertson
  • 2,742
  • 3
  • 25
  • 43
0

I faced the same problem and find out it was because of res.redirect in put.

Change res.redirect('path') to res.redirect(303, 'path')

In Put and Delete, if you want to redirect to get address, you should pass 303 as first parameter. (source)

yaya
  • 7,675
  • 1
  • 39
  • 38