I’m searching a solution for the following problem:
I get the IDs of a model from an external context. Then I use Ember Data to retrieve records from our backend base on the IDs which I got before. Therefore I use this.get('store').query('material', {ids: [1,2,3,4...] }) but query is not cached by Ember Data. So the network request is made over and over again. I would need something like findRecords or findRecordsById. I searched through the API and I found that there is a private method named findByIds (for details click here). But there are two gotchas:
I don’t want to use a private API
findByIds seems to ignore coalesceFindRequests: true
What is the best way to solve this? Do I have to write this functionality on my own or is there already somewhere a implementation?
@matheos thanks for your response. So you think there is no implementation in ember-data? Because often I just don’t find what I’m searching for in the docs. Your idea is a good starting point but I also need to consider the fact that some of the ids in the array_of_ids are not loaded already.
For example: id 1, 2, 3 were fetched before and id 4, 5, 6 weren’t fetched. So I could retrieve 1, 2 and 3 directly from the store and 4, 5 and 6 from the backend. Then I want to return 1, 2, 3, 4, 5 and 6 after 4, 5 and 6 arrived.
I don’t know of any existing public implementation in ember-data, so the best workaround I would use would be using the recordIsLoaded method to determine if ember-data has already loaded the record.
getResults(array_of_ids) {
var results = [];
var record;
array_of_ids.forEach(function(value) {
// check if already loaded
if (this.store.recordIsLoaded('records', value) === false) {
record = this.store.findRecord('records', value);
} else {
record = this.store.peekRecord('records', value);
}
// add to results array
results.push(record);
});
return results;
}
or if you have an api implementation for retrieving multiple records from query-params:
getResults(array_of_ids) {
var results = [];
var ids_to_fetch = [];
var record;
array_of_ids.forEach(function(value) {
// check if already loaded
if (this.store.recordIsLoaded('records', value) === false) {
ids_to_fetch.push(value);
} else {
results.push(this.store.peekRecord('records', value));
}
});
if (ids_to_fetch.length > 0) {
this.store.query('records', { ids: ids_to_fetch }).then(function(records) {
results = results.concat(records);
});
}
return results;
}