How can I find records by id and don't always make a network request


#1

Hello!

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?

Thanks for every tip and hint Bye


#2

Maybe use the peekRecord method in a loop that adds to an array of objects?

getResults(array_of_ids) {
  var results = [];

  array_of_ids.forEach(function(value) {
    results.push( this.store.peekRecord('records', value) );
  });

  return results;
}

#3

@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.


#4

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;
}