I'm having a problem where my backbone model isn't parsing something correctly. Here is the listing.js:
SpendYourSavings.Models.Listing = Backbone.Model.extend({
urlRoot: "api/listings/",
images: function() {
this._images = this._images || new SpendYourSavings.Collections.Images([], { listing: this });
return this._images;
},
reviews: function() {
this._reviews = this._reviews || new SpendYourSavings.Collections.Reviews([], { listing: this });
return this._reviews;
},
shop: function() {
this._shop = this._shop || new SpendYourSavings.Models.Shop([], { listing: this });
return this._shop;
},
parse: function(data) {
if(data.images) {
this.images().set(data.images, { parse: true });
delete data.images;
}
if(data.reviews) {
this.reviews().set(data.reviews, { parse: true });
delete data.reviews;
}
if(data.shop) {
this.shop().set(data.shop, { parse: true });
delete data.shop;
}
return data;
}
});
Images and reviews work, but shop doesn't quite work. It sets the attributes of shop correctly, but it doesn't set the image properly.
Here is the shop.js:
SpendYourSavings.Models.Shop = Backbone.Model.extend({
urlRoot: "/api/shops",
reviews: function() {
this._reviews = this._reviews || new SpendYourSavings.Collections.Reviews([], {});
return this._reviews;
},
listings: function() {
this._listings = this._listings || new SpendYourSavings.Collections.Listings([], {});
return this._listings;
},
user: function() {
this._user = this._user || new SpendYourSavings.Models.User([], {});
return this._user;
},
image: function() {
this._image = this._image || new SpendYourSavings.Models.Image([], {});
return this._image
},
parse: function(data) {
console.log("shop parse data: " + data);
debugger
if(data.listings) {
this.listings().set(data.listings, { parse: true });
delete data.listings;
}
if(data.reviews) {
this.reviews().set(data.reviews, { parse: true });
delete data.reviews;
}
if(data.user) {
this.user().set(data.user, { parse: true });
delete data.user;
}
if(data.image) {
debugger
this.image().set(data.image, { parse: true });
delete data.image;
}
return data
}
});
The parse function in the shop.js never even when I receive a shop in the listing.js parse function! shop.image()
doesn't get set to an image model properly, so I have to call something wonky like shop.get('image').url
to get the url.
Presumably, the reason you're memoizing the image model in the shop is to maintain listeners and keep a single instance of that model around.
Collection#set
takes a parse
option that tells it to call parse on all the models that were set on the collection. Model#set
is the method called immediately after calling parse using the attributes returned from parse
.
In this case, we want to call #set
on the associated shop
model using the parsed attributes. So first lets call parse
. It should look something like this:
SpendYourSavings.Models.Listing = Backbone.Model.extend({
urlRoot: "api/listings",
images: function() {
this._images = this._images || new SpendYourSavings.Collections.Images([], { listing: this });
return this._images;
},
reviews: function() {
this._reviews = this._reviews || new SpendYourSavings.Collections.Reviews([], { listing: this });
return this._reviews;
},
shop: function() {
// Notice the first argument is an object when initializing models.
this._shop = this._shop || new SpendYourSavings.Models.Shop({}, { listing: this });
return this._shop;
},
parse: function(data) {
if(data.images) {
this.images().set(data.images, { parse: true });
delete data.images;
}
if(data.reviews) {
this.reviews().set(data.reviews, { parse: true });
delete data.reviews;
}
if(data.shop) {
var shopParams = this.shop().parse(data.shop);
this.shop().set(shopParams);
delete data.shop;
}
return data;
}
}
});