I'm working on a web application that is powered by a restful API written with Python's CherryPy framework. I started out writing the user interface with a combination of jQuery and server side templates, but eventually switched to Backbone.js because the jQuery was getting out of hand.
Unfortunately, I'm having some problems getting my models to sync with the server. Here's a quick example from my code:
$(function() {
var User = Backbone.Model.extend({
defaults: {
id: null,
username: null,
token: null,
token_expires: null,
created: null
},
url: function() {
return '/api/users';
},
parse: function(response, options) {
console.log(response.id);
console.log(response.username);
console.log(response.token);
console.log(response.created);
return response;
}
});
var u = new User();
u.save({'username':'asdf', 'token':'asdf'}, {
wait: true,
success: function(model, response) {
console.log(model.get('id'));
console.log(model.get('username'));
console.log(model.get('token'));
console.log(model.get('created'));
}
});
});
As you can probably tell, the idea here is to register a new user with the service. When I call u.save();
, Backbone does indeed send a POST request to the server. Here are the relevant bits:
Request:
Request URL: http://localhost:8080/api/users
Request Method: POST
Request Body: {"username":"asdf","token":"asdf","id":null,"token_expires":null,"created":null}
Response:
Status Code: HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 109
Response Body: {"username": "asdf", "created": "2013-02-07T13:11:09.811507", "token": null, "id": 14, "token_expires": null}
As you can see, the server successfully processes the request and sends back an id
and a value for created
. But for some reason, when my code calls console.log(u.id);
, I get null
, and when my code calls console.log(u.created);
, I get undefined
.
tl;dr: Why isn't Backbone.js persisting changes to my objects after a call to save()
?
Edit:
I've modified the above code so that the model properties are accessed using the get function in a success
callback. This should solve any concurrency problems with the original code.
I've also added some console logging in the model's parse
function. Oddly enough, each of these is undefined
... Does that mean that Backbone.js is failing to parse my response JSON?
Edit 2: A few days ago, I found out that issue was actually a custom header that I was adding to every request to enable HTTP Basic Authentication. See this answer for details.
Model.urlRoot
instead ofModel.url
, but that's not the problem here). Earlier revisions of your code had problems, but are you absolutely sure that the exact code in your current edit still fails? – Metabolite