Backbone model .toJSON() doesn't render all attributes to JSON

backbone.js, javascript

Solution

The `toJSON()` method just returns a shallow clone of the model's `attributes` property.

From the annotated Backbone.js source:

toJSON: function(options) {
  return _.clone(this.attributes);
}

Without seeing more of your code, it looks like you directly set properties on the model object, rather than using the `set` function to set model attributes.

I.e. don't do this:

model.name = "item";

do this:

model.set("name", "item");

EDIT:

For your specific issue, it's possible that you called toJSON before the model had finished loading from the server.

E.g. This won't always work as expected:

var model = new Goal({id: 123});
model.fetch();
console.log(model.toJSON());

But this will:

var model = new Goal({id: 123});
model.fetch({
  success: function() {
    console.log(model.toJSON());
  }
});

Problem

I need to render a model's attributes to JSON so I can pass them into a template. Here is what a render() function for a view looks like: ``` render: function() { console.log(this.model); console.log(this.model.toJSON()); $(this.el).html(this.template(this.model.toJSON())); return this; }, ``` Here is the attributes output after doing console.log(this.model): ``` created_at: "2012-04-19" id: "29" name: "item" resource_uri: "/api/v1/item/29/" updated_at: "2012-04-21" user: "/api/v1/user/9/" ``` Here is the model's JSON output after doing console.log(this.model.toJSON()): ``` id: "29" __proto__: Object ``` What happened? Edit: Here is the instantiation: ``` var goal = new Goal({id: id}); goal.fetch(); var goalFullView = new GoalFullView({ model: goal, }); ``` Here are the contents of the new view: ``` console.log(this.model.attributes); console.log(this.model.toJSON()); ``` Here is what the console says: ``` Object created_at: "2012-04-23" id: "32" name: "test" resource_uri: "/api/v1/goal/32/" updated_at: "2012-04-23" user: "/api/v1/user/9/" __proto__: Object Object id: "32" name: "test" __proto__: Object ``` If the toJSON is supposed to make a clone of the attributes, why doesn't it copy the correct name or why doesn't it copy the created_at, updated_at fields? Edit 2: Here is the model: ``` var Goal = Backbone.Model.extend({ // Default attributes for Goal defaults: { name: "empty goal", }, // Check that the user entered a goal validate: function(attrs) { if (!attrs.name) { return "name is blank"; } }, // Do HTTP requests on this endpoint url: function() { if (this.isNew()) { return API_URL + "goal/" + this.get("id") + FORMAT_JSON; } return API_URL + "goal/" + FORMAT_JSON; //API_URL + "goal" + FORMAT_JSON, }, }); ``` Edit 3: I figured out that I need to use the success callback from fetch to render a view that uses the model: goal.fetch({success: function(model) { var goalFullView = new GoalFullView({ model: goal, }); }});

Original source