Backbone.js: Collection.get() issues
-
25-10-2019 - |
Question
Using Backbone.js, trying to do a simple get() on a collection after fetching items from server.
Fetch seems to work fine. However, when I try to get an item by id from the collection, I'm getting the unexpected result of undefined, instead of a model.
Here's my backbone items code:
Model.Scenario = Backbone.Model.extend({
defaults: function() {
return {
title: 'Scenario',
answer: null,
};
}
});
Collection.Scenarios = Backbone.Collection.extend({
model: Model.Scenario,
url: "data.php",
});
Then the obj creation/fetch w/in a router method:
var Router = new (Backbone.Router.extend({
routes: {
":id" : "page",
"" : "page"
},
initialize: function() {
_.bindAll(this, 'page');
this.scenarios = new Collection.Scenarios();
this.scenarios.fetch();
console.log(this.scenarios);
console.log(this.scenarios.get(1));
console.log(this.scenarios.get(2));
Backbone.history.start();
},
}))();
Finally, here's what's logged to the debugger (so you can see the Collection is being populated):
child
_byCid: Object
_byId: Object
1: child
2: child
3: child
4: child
7: child
10: child
11: child
12: child
13: child
14: child
15: child
16: child
17: child
18: child
19: child
20: child
21: child
22: child
23: child
26: child
27: child
28: child
__proto__: Object
length: 22
models: Array[22]
__proto__: ctor
undefined //first call to get(id)
undefined //2nd call to get(id)
I'm stumped. Sorry for the long post, but would appreciate any insight on what I'm missing. Thanks.
Solution
My first thought is that the fetch() has not returned by the time you're doing your .get().
But, if what you posted is exactly what is happening, then the first console.log(this.scenarios) is showing that is IS loaded.
At any rate, you may want to try putting the console.logs into the success: event of the fetch, just to make sure that is not the issue.
My second thought is that the id for the models is not being set right.
Backbone.Model defaults to using the property "id" as the ID for a model, Collection.get(id) returns the model with the id you passed in.
So, does the response from data.php have an id property?
Try instead:
var Router = new (Backbone.Router.extend({
routes: {
":id" : "page",
"" : "page"
},
initialize: function() {
_.bindAll(this, 'page');
this.scenarios = new Collection.Scenarios();
this.scenarios.fetch({
success: function(coll, resp) {
console.log(coll);
console.log(coll.first());
console.log(coll.last());
});
Backbone.history.start();
},
}))();
Which should return the first and last model, and take the ID issue out of the picture.
If that works, what do the models show for the id property (coll.first().id)?