I have a question related to contained backbonejs model objects. Using yeoman backbone generator described at https://github.com/yeoman/generator-backbone, I created a backbone application to test how a model object that contains another model object is being sent as json to the backend server.
I added two models contact and address to this test application.
yo backbone:model contact
yo backbone:model address
Contact object contains one address object. Contact and address backbone model objects are shown below. The init function in the generated main.js is also shown below. The console log is shown below. Ignore the POST error since there is no endpoint contacts.
My question is: in the Chrome browser Developer Tools window, network tab the request payload is:
{"name":"John Doe"}
What changes are needed to the backbone model objects so that the request payload will have the contained address object also? Thanks. I want the payload to look like this:
{
"name": "John Doe",
"address": {
"addressLine1": "Somewhere"
}
}
From console in the Developer Tools window, I can confirm addressLine1 is 'Somewhere' in the contained address object :
Inside Contact.initialize
address.js:14 Inside Address.initialize
contact.js:24 Inside Contact.getAddress
main.js:12 Hello from Backbone! name = John Doe addressLine1 = Somewhere
contact.js:21 Inside Contact.validate
main.js:22 return value from save [object Object]
jquery.js:8630 POST http://localhost:9001/contacts 404 (Not Found)
...
main.js:19 Error [object Object]
From main.js
init: function () {
'use strict';
var myContact = new Test.Models.Contact();
console.log('Hello from Backbone! name = ' + myContact.get('name') + ' addressLine1 = ' + myContact.getAddress().get('addressLine1'));
var rv = myContact.save(null,{
success: function(response) {
console.log('Success ' + response);
},
error: function(response) {
console.log('Error ' + response);
}
});
console.log ('return value from save ' + rv);
} };
From contact.js
/*global Test, Backbone*/
Test.Models = Test.Models || {};
(function () {
'use strict';
Test.Models.Contact = Backbone.Model.extend({
url: '/contacts',
initialize: function() {
console.log ('Inside Contact.initialize');
this.address=new Test.Models.Address();
},
defaults: {
name: 'John Doe'
},
validate: function(attrs, options) {
console.log ('Inside Contact.validate');
},
getAddress: function() {
console.log ('Inside Contact.getAddress');
return this.address;
},
parse: function(response, options) {
console.log ('Inside Contact.parse');
return response;
}
});
})();
From address.js
/*global Test, Backbone*/
Test = {}; // a global object
Test.Models = Test.Models || {};
(function () {
'use strict';
Test.Models.Address = Backbone.Model.extend({
url: '',
initialize: function() {
console.log ('Inside Address.initialize');
},
defaults: {
addressLine1: 'Somewhere'
},
validate: function(attrs, options) {
console.log ('Inside Address.validate');
},
parse: function(response, options) {
console.log ('Inside Address.parse');
return response;
}
});
})();
Call stack when I set a breakpoint at contact validate function:
validate (contact.js:21)
_validate (backbone.js:568)
save (backbone.js:465)
init (main.js:14)
(anonymous) (main.js:29)
fire (jquery.js:3099)
fireWith (jquery.js:3211)
ready (jquery.js:3417)
completed (jquery.js:3433)
When the above break point is triggered, I can verify this object has address information:
this
child {cid: "c1", attributes: {…}, _changing: false, _previousAttributes: {…}, changed: {…}, …}
address:child
attributes:{addressLine1: "Somewhere"}
changed:{}
cid:"c2"
_changing:false
_pending:false
_previousAttributes:{}
__proto__:Backbone.Model
attributes:{name: "John Doe"}
changed:{}
cid:"c1"
_changing:false
_pending:false
_previousAttributes:{}
__proto__:Backbone.Model
Thanks a lot.