How to cache query result in ember data

I’m not an Ember expert but I think you can address your problem with a pure JS solution.

Given Ember Data queries return Promises, e.g. return this.store.findAll('blog-post'); // => Promise, we can cache promises in a simple object with higher order functions (functions that return functions). The object cache could be replaced with localStorage, sessionStorage, Map or even WeakMap but I’m using the object cache to make things simple to understand.

What you want to essentially do is to replace following call:

return this.store.findAll('blog-post');

with something more or less like:

return cachedStore.findAll('blog-post');

actually, with the solution below it might look more like:

return cachedStore.call(this, 'findAll', 'blog-post');

As a result, you will request data once and always return from cache in subsequent calls.

Let me show you how the implementation might look like:

var cachedStore = (function () {
  // Your cache - in this case simple object literal
  var cache = {};

  // Actual method that will check cache for results before trying to query services
  return function (method) {
    var args = Array.prototype.slice.call(arguments, 1);
    var serializedArgs = JSON.stringify(args);

    if (!(serializedArgs in cache)) {
      cache[serializedArgs] = this.store[method].apply(this, args);
    }
    return cache[serializedArgs];
  };
}());

And here’s a sample usage:

// Fires a request
cachedStore.call(this, 'findAll', 'blog-post');
// Returns from cache
cachedStore.call(this, 'findAll', 'blog-post');
// Returns from cache
cachedStore.call(this, 'findAll', 'blog-post');

// Fires a request
cachedStore.call(this, 'findRecord', 'blog-post', 123);
// Returns from cache
cachedStore.call(this, 'findRecord', 'blog-post', 123);
// Returns from cache
cachedStore.call(this, 'findRecord', 'blog-post', 123);

Does that help in any way?

Leave a Comment

tech