Reputation: 4926
There is a /users
url in my ember application. I am using RESTAdapter
to fetch data from server. When a template showing list of users
is loaded, it loads the latest updated data from the server (e.g. if I make changes in one of the row in users table, say changing the name of the user, I get that change reflected at front-end as well). But if I delete the user from database, I still get that user in the users' list at the front-end.
The model-hook for users route simply returns the list of users from server:
this.store.find('user').then(onSuccess, onError);
When I try to do any operation on deleted user (say updating it's name at front-end), I get an error (which is obvious as the user is no more in the database and server responds with an appropriate error). How to force emberjs to load the list of users that are present in the database and not just in local ember-data store? Also, why local ember-data store is in-sync with database for updation (and addition as well) but not for deletion?
Upvotes: 1
Views: 620
Reputation: 57502
To overcome this problem, you can unload all of the records from the store and then call find():
this.store.unloadAll('user');
this.store.find('user').then(
function(d) {
console.log(d.get('length')); // store now only contains the users returned from the server
}
);
Upvotes: 1
Reputation: 2861
The problem is explained at the github issue.
The store has a cache for each model type, then when the store fetch data with the _findAll method method, it does not assume that is returning all the data, so the following steps are applied
store.pushMany(type, payload); // push the server response data to the local store
store.didUpdateAll(type); // update record with the most up-to-date record
return store.all(type); // return all the record in the local store
It will not take in consideration any record deletion as it is discussed in the issue, in this case the new response data would be added to the local store if a record with its same primaryKey cannot be found or in the other case, it will update the local copy.
I created a test to check the defined behaviour:
test('store.findAll does not manage record deletion', function() {
$.mockjaxClear();
$.mockjax({ url: '/categories', dataType: 'json', responseText: {
categories:[ {id: 1, name: "Name1"}, {id: 2, name: "Name2"} ]}});
var store = this.store();
stop();
store.find('category').then(function(result) {equal(result.get('length'), 2, 'the new item returned with ajax is added to the local store'); $.mockjaxClear(); $.mockjax({ url: '/categories', dataType: 'json', responseText: { categories:[ {id: 3, name: "Name3"}, ]}}); store.find('category').then(function(result) { equal(result.get('length'), 3); $.mockjaxClear(); $.mockjax({ url: '/categories', dataType: 'json', responseText: { categories:[ {id: 3, name: "Name4"}, ]}}); store.find('category').then(function(result) { equal(result.get('length'), 3); equal(result.objectAt(2).get('name'), 'Name4', 'the old item returned with the new ajax request updates the local store'); start(); }); });
});
});
As you pointed something like find('modelName', {}) would solve your issue:
this.store.find('user', {})
Upvotes: 1
Reputation: 4926
It seems that this is a known bug in Emberjs. The workaround that I found (accidently) was : supply any arbitrary parameter to find()
method and the data loaded will be the same one fetched from the server.
Below an example shows that xyz
parameter is being passed with value abc
.
this.store.find('user', {xyz:"abc"}).then(onSuccess, onError);
I am not sure if this is THE RIGHT WAY to do it, but it works for me. The other solutions would be those which are mentioned in the link (like sending some metadata from server i.e. maintaining the list of deleted records).
But I still couldn't figure out why this happens in case of DELETE
only (and not in case of POST
and PUT
).
I am not sure if this really is a problem or I just do not understand EmberJS that much. Any help or comments on the same would be much appreciated.
Upvotes: 1