I have a restful Todo List implemented with React and Backbone.
For now, I'm not talking to a database; just have an array var mytodos = [];
in my server.js.
Here's the server code for POST (using Express):
app.post('/todos', function(req, res) {
var todo = {
id: mytodos.length,
title: req.body.length,
completed: req.body.completed
};
mytodos.push(todo);
console.log('POST ' + JSON.stringify(todo));
res.send(todo);
});
When I add an item to the list, I see two POSTS being made for some reason.
POST: {"id":0,"title":"test","completed":false}
POST: {"id":1,"title":"test","completed":false}
In Chrome Dev. Mode, I see:
PUT localhost/todos/0 404 (Not Found)
PUT localhost/todos/1 404 (Not Found)
Two PUT requests!
Trying to reason through it - save()
is called which calls sync()
. Since the model doesn't have an id
yet (only cid
), it make a POST request and a todo (id = 0) is added to mytodos
which then updates the model on the client (adds the id
attribute). Since a change was detected, it does another save()
which PUTS it to the server (<-- may very well be wrong here; not sure if the updated model would cause a PUT).
This might explain the PUT, but not the double POST.
Here is where save()
is getting called (under TodoApp = React.createClass...
:
componentDidUpdate: function() {
this.props.todos.forEach(function(todo) {
console.log('componentDidUpdate: ' + todo.id); // logs: undefined, 0, 1
todo.save();
});
},
...
save: function(todo, text) {
console.log('Save: ' + todo.id); // only logged on update
todo.save({title: text});
this.setState({editing: null});
},
...
}
Why does this happen?
Why is it PUT
ting in addition to POST
ing? And why is it doing it twice?
Edit:
I resolved the double POST by changing create
to add
- reference to where I got help.
The last problem is a PUT 404 (Not Found)
for an item that is definitely on the server. Interestingly, the PUT
is not going through my server it seems. My server only logs the POST
. The PUT
is being logged somewhere else.
I resolved the double POST by changing create
to add
More specifically a certain event was triggering a Backbone.Collection.create
call which according to this syncs with the server.
In my React code, I have a componentDidUpdate
which calls Backbone.Model.save
which also tries sending to the server. Here.
Because the event caused both create
and save
to be executed, POST was firing twice.