I’ve been playing around with Backbone.js and ran into something a bit unexpected. It seems that toJSON() (and as a result of attributes) will only return a JSON object if I explicitly set the attributes. Here’s the issue:
- Extend/inherit a sample object with some data
- grab the resulting constructor
- instantiate/new an instance
- call the
toJSON()function
I expected the call to return my object with all attributes (inherited and bound), but instead I got back an empty {} object.
Here’s the sample code:
var TestModelConstructor = Backbone.Model.extend({ name: "test", num: 483 });
var testinstance = new TestModelConstructor;
console.log(testinstance.name); //prints: test
console.log(testinstance.num); //prints: 483
console.log(JSON.stringify(testinstance.toJSON())); //prints: {}
console.log(testinstance.attributes); //again empty object
testinstance.newattr = "adding new attribute";
console.log(testinstance.attributes); //{} ????
//either set explicitly by calling "set" or via constructor/initialize
testinstance.set({ label: "i can setz attributez" });
console.log(JSON.stringify(testinstance.toJSON()));
//{"label":"i can setz attributez"}
console.log(testinstance.attributes); //{"label":"i can setz attributez"}
Either this behavior is strange or I missed something in the documentation.
I think you should be using the
defaultsparameter to theextendfunction to set the defaults. Parameters passed to the extend function will be members on the class rather than attributes, which is whattoJSONuses.See the defaults documentation for more details.
To be clear, the attributes
Backbone.Modeluses are stored in theattributesmember of the class rather than on the actual class itself. This avoids confusing actual model data with functions that you call on the model and settings that you use to configure the model. It’s these functions and settings that you’re creating/setting when you pass arguments to theModel.extendfunction.So when you’re trying to set
testinstance.newattryou should actually usetestinstance.attributes.newattrinstead. This is what the.setmethod is actually doing behind the scenes, so I’d recommend just using.set.Again, the attributes documentation has more details