Why records property is not updating with fetch?
DmitryFillo opened this issue · 14 comments
I use localStorage collection, works great. But I want use storage event for updating collection in many tabs. Idea: do fetch() when storage event fires.
bindStorageEvent : function() {
var _this = this;
$(window).on('storage.'+this.localStorage.name, function(e) {
if(e.originalEvent.key === _this.localStorage.name) {
_this.fetch();
}
});
},
unbindStorageEvent : function() {
$(window).off('storage.'+this.localStorage.name);
}
But this shouldn't work as expetcted because records property will not be updated with fetch and save() method use records prop. And so all actual data which came from one tab will be rewrited by old data from another tab.
So I rewrited code in this way:
bindStorageEvent : function() {
var _this = this;
$(window).on('storage.'+this.localStorage.name, function(e) {
if(e.originalEvent.key === _this.localStorage.name) {
// the dirtiest records update way, only for test
var store = _this.localStorage.localStorage().getItem(_this.localStorage.name);
_this.localStorage.records = (store && store.split(",")) || [];
_this.fetch();
}
});
},
unbindStorageEvent : function() {
$(window).off('storage.'+this.localStorage.name);
}
And it works great.
Suggested solution: I think that we can put this code to the another method in the localStorage object (records_update) and call this method from constructor and from Backbone.sync() when doing fetch() or from findAll() before getting particular model. I think this property must be updated on fetch, not only at the collection initialization time.
So if I'm understanding it correctly, every time you run fetch()
, the in-memory model should update with whatever's in the localStorage
, overwriting the data in the model/collection. I'll pull a test together to see if I can verify this behaviour.
I'm removing the 2.0
milestone until I can understand what needs to happen here. I'm thinking it might be a bug but I'm not sure.
I have the same problem.
If I replace "this.records" in the function "findAll" with "localStorage.getItem(this.name).split(',')" everything is working.
model.LocalStorage and the browser localStorage seem to be out of sync.
Hi @chris136 - is the local storage being updated in multiple places? e.g. are there two models referencing the local storage record?
No, just one model. I use it to save calendar events created via drag and drop. I noticed newly created events were missing when I switched a week back and forth. But after a complete site reload, the events were back where they were created.
After this little fix I mentioned before, everything worked as intended.
Thanks for the information @chris136 If I understand this correctly, what's happening is:
- Fetch all events from localStorage
- Add new event
- Move away from view
- Move back to view
- Step 1. fires again but the newly added item in localStorage isn't in your view
Basically, once there's a list of records in the collection, fetch
is just returning that list instead of checking the localStorage again.
I can have a look at this over the weekend and try to re-create the issue in a test environment.
Hi @chris136
Would it be possible for you to check the version of Backbone.localStorage that you're using? I've been trying to recreate this in tests and the output seems to be acting the way I'd expect in version 2.0.0.
@scott-w according to the changelog I use version 1.1.16 (January 22, 2015).
I installed it via NPM @2.x and it said version 2.0.0
@scott-w yes, that is the version where I noticed the problem.
I try to make a minimal test case if I find the time this week.
Any updates on this issue? or is there any workaround?
Cheers!
I fixed this in my backbone fork.
Look at the following commits:
blikblum/nextbone@8054cdd
blikblum/nextbone@e183cce
Should not be hard to make a PR. Currently i'm on a slow internet connection so cannot do it myself