[AC-2633] Alloy collection.get returning undefined
GitHub Issue | n/a |
---|---|
Type | Bug |
Priority | n/a |
Status | Resolved |
Resolution | Not Our Bug |
Resolution Date | 2013-05-14T22:53:56.000+0000 |
Affected Version/s | n/a |
Fix Version/s | n/a |
Components | Alloy |
Labels | Alloy, Backbone, Get, collection, model |
Reporter | Joe Moretti |
Assignee | Shak Hossain |
Created | 2013-05-14T14:32:58.000+0000 |
Updated | 2016-03-08T07:41:43.000+0000 |
Description
If I have a collection called catalogs and I want to get a model (id 1234) from that collection by id, based off of the documentation for backbone.js, I believe I should be able to:
var selectedCatalogID = '1234'
var catalog = null;
catalog = catalogs.get(selectedCatalogID);
but when I introspect catalog after this runs, its value is undefined;
A work around I have been using is:
var selectedCatalogID = '1234'
var catalog = null;
for (var i = 0, l = catalogs.models.length; i < l; i++){
if (catalogs.models[i].id == selectedCatalogID){
catalog = catalogs.models[i];
break;
}
}
which does work as expected, but isn't as clean as using backbone's collection.get();
This would be better suited as a Q&A question as it is not clear to me that this is an issue with Alloy and/or Backbone versus perhaps an issue with your code. Please start with a Q&A question next time before escalating to a ticket. I'm guessing you are incorrectly using a string when you should be using an integer for the get() call. Though I am guessing because the code for your model has not been provided. I'll explain inline in the code you did provide:
I am sorry for not posting in the Q&A prior to creating an issue. I felt pretty confident this was a bug and that is why I started here. I tested with a === operator and the workaround continued to function properly. Additionally, I verified that catalogs.models[i].id is a string type. If you do not feel this is an issue, we can close it and I will repost to the Q&A.
Did you set the idAttribute of the model? It would help to see your model code.
I am using a modified version of TiTouchDB (https://github.com/jmoretti/ti_touchdb/tree/attachmentFilePath) as the persistance adapter for my model.
The value of the catalogs collection right before the problem code is:
Reviewing the persistance adapter in use (code below), I do see that idAttribute appears to be set in the module.exports.afterModelCreate function.
right, Backbone.Collection.get() relies on the idAttribute, in this case
_id
. You are storing your ids in the wrong field, since you are referencingid
. So in any case in your model where you are directly referencingmodel.id
you should probably be usingmodel._id
. The safest way actually would be to use the model's own idAttribute as the key, so perhaps you should change those direct references tomodel.id
to bemodel[model.idAttribute]
.That did not correct my issue; however, it seems that Backbone was not adding the models to the _byId hash table which is used by the Backbone.Collection.get() method. I was able to work around it in my sync adopter by adding a line of code to the snippet below from the sync adapter:
I would haves suspected that Backbone.js and ergo Alloy would have handled this (it looks like it is handeld in the Backbone.Collection.add() method). It appearsBackbone is using idAttribute to set Model.id appropriately.
Ok, forgive me, I didn't write this sync adapter, so I am reverse engineering it as I dig into this. It appears that models were being added to the collection by the array.push() method directly into the Collection.models array. Looking at this previously (the same snippet from my previous comment), I had always read this as collection.push(m); After correcting this code to use the Backbone.Collection.push() method, all is working as expected. I apologize again for posting this in the wrong forum and appreciate your help. I will make certain to get a pull request in with this change to the owner of the sync adapter github repo.