angular-restmod
angular-restmod copied to clipboard
issue with shared model plugin and search/fetch
Im not sure if this is a bug or just my misusing the api heres the scenario:
Basically, what Im trying to do can be reproduced if you call search twice on a model that is using the shared_model plugin. For instance:
module.controller('ContactsIndexController', function($scope, Contact) {
$scope.collection = Contact.$search();
$scope.collection = Contact.$search();
// also for further sake of example the following yields the same results
// Contact.$search().$then(function(result){
// $scope.collection = this;
// });
// Contact.$search().$then(function(result){
// $scope.collection = this;
// });
});
The issue is on second call of search, the shared model plugin is finding the model in cache when decoding, but then mysteriously seems to not return the actual found result back the the main collection array.
The above is not a good example but, basically the real issue Im having is, when I move to another sibling level state into my application, lets say from contacts.index to dashboard.index, then back to contacts.index, which instantiates a brand new controller, it calls contact.search again, and it wont return the actual search results since theyve been cached but for some reason, although decode is returning the result, its not being added back into the collection.
Am I missing something, or is there a better way to do the above? Or is this a bug?
I believe you are experiencing the same problem as me. But I'm having the problem if I re-use a shared model in a Collection when I previously used it as a relation only. Is seems to have something to do with the $scope the object is in. The moment you create the second collection, the $scope for the model is changed from the first collection scope to the second collection scope. This seems to remove the model from the first collection.
I circumvented my problem by disabling the cache when the model is used inside a scope. But that does not work in your case.
Yep, there is a problem with scopes and SharedModel, thats the reason why SharedModel
is not officially released (I commited the file by mistake a couple of months ago).
I'm currently revising the implementation, the official plugin should be out soon.
Thanks! I'll check it out when it's released. I'm using it for a couple of models in my application.
@eborned @iobaixas
FYI: here is the semi fixed implementation Ive made. I cant remember if I fully fixed the issue or not, or whether this only solves multiple models using the plugin overriding each others data (model 1 pk = 1, model 2 pk = 1 == bad data). (I cant remember because the apps I used it on, I rearchitechted how I was loading the relations, I.E. relations were all defined on a DataStore model, which still seems pretty hacky having to do that). So I think it solves another problem entirely, but @iobaixas not sure if you solved this one yet with reworking.
/**
* @mixin SharedModel
*
* @description
*
* Enables caching instances by primary key so a resource with a given id will always refer to the same instance.
*/
// 'use strict';
angular.module('adminfront').factory('RecordUniqueness', ['restmod', function(restmod) {
return restmod.mixin({
$extend : {
Model: {
cache: {},
}
}
}, function() {
this
// this will cache record by its type within cache, as apparently cache
// variable as assigned above will be shared between models
.define('Model.$cache', function(){
var self = this;
if(self.cache.hasOwnProperty(self.identity())) {
return self.cache[self.identity()];
} else {
return self.cache[self.identity()] = {};
}
})
.define('Model.$new', function(_key, _scope) {
var self = this;
if(_key) {
// search for instance with same key, if key is found then return instance
if(self.$cache().hasOwnProperty(_key)) {
return self.$cache()[_key];
} else {
return (self.$cache()[_key] = this.$super(_key, _scope));
}
} else {
return this.$super(_key, _scope);
}
})
// override record.$decode to update cache on decoding.
.define('Model.$decode', function(_raw, _mask) {
var self = this,
result = this.$super(_raw, _mask);
if(result.$pk) {
self.$cache()[result.$pk] = this;
}
return this.$super(_raw, _mask);
});
});
}]);
Thanks @jasonayre, didn't saw your post until now!
Any news on this issue? What was your plan with the new implementation? Maybe I can help or test things out for our new application.
Also curious on how this support is coming.