20

I was told that in order to not make a request all the time, one can use .all() method to load data that is kept in the store. But how does Ember deal with cache? I have a couple of questions.

How do you control cache? When do you use .find() and when .all(). Do you use .find() and then .all()? For how long?

Does .all() have some expiration date so that after some time it can make a new request? Or it uses Local Storage so that I have to clear it manually?

Suppose that I have some data I'd like to refresh only once a week? How should I go about this? Now every time I enter or re-visit the same route a new request is made. How can I avoid this?

Community
  • 1
  • 1
wryrych
  • 1,765
  • 4
  • 20
  • 31
  • did you take a look at this open issue: https://github.com/emberjs/data/issues/235 – intuitivepixel May 14 '13 at 07:29
  • @intuitivepixel I'd rather to know how can I load data when an app starts (not via routes as I don't have to update it so often). Is it possible? – wryrych May 15 '13 at 08:20
  • I tried to answer your other question ... :) – intuitivepixel May 15 '13 at 08:48
  • Basic doubt, If my data in backend changes very often due to multiple service I expose api to, which forces me to reload the data always with request. I don't find the use of a Ember Store now. Ember Model is also getting completed every time when try to define complicated model. Is Ember Store and Ember Model Needed? Is Ajax and response alone can't be used? This have been my basic doubt for very long time. – Ganesh Arulanantham Feb 10 '17 at 14:38

2 Answers2

21

So will start by answering question from your comment:

I'd rather to know how can I load data when an app starts (not via routes as I don't have to update it so often). Is it possible

So OK technically this is still via routes, but the best way to load data when an app "starts" is via the Application Route's model hook.

App.ApplicationRoute = Ember.Route.extend({
  model: function({
    return App.Post.find();
  })
})

The router will wait for promise returned by find() to resolve, so you can be sure that response from server has come back before any other routes are entered.

How do you control cache?

Mostly you don't worry about it. You can refresh() an individual record after some timeout if needed.

When do you use .find() and when .all(). Do you use .find() and then .all()? For how long?

Depends what you want to achieve. In our app we use find() in the application route, then either all() or a filter() in other routes.

Does .all() have some expiration date so that after some time it can make a new request?

Nope. It will never make a new request

Or it uses Local Storage so that I have to clear it manually?

It does not use local storage, records are in memory. So for sure an F5 will clear the cache.

Suppose that I have some data I'd like to refresh only once a week? How should I go about this? Now every time I enter or re-visit the same route a new request is made. How can I avoid this?

So OK let's assume you use find() only in the application route, and that user keeps browser open for 1 week and the records have expired. There are many ways to refresh, what's easy/best depends on if they all expire at once or if they time-out one at a time.

  • Have some timer checks for expired records and calls refresh() as needed.
  • Have a Ping model that you update on some schedule. When server responds to update it can sideload any changed records.
  • Or can just refresh the browser once per week (via window.location...)
Mike Grassotti
  • 19,040
  • 3
  • 59
  • 57
  • Isn't `model` hook for one particular model? When loading a few models at once, should I use `setupController` hook? – wryrych May 26 '13 at 06:42
  • True, model should return one model (or maybe an array) so I get why you'd expect to use setupController. What's important is the ember router will wait for the promise returned by the model hook to resolve before moving on. It runs model() on every route, them moves on to setupController(). You can use this to make sure that all model data you need is loaded in advance. In our app the model hook calls App.Network.find() to load data for a network. Our API responds with the network json and sideloads all related models. Once AppRoute.model() hook is done all our data is loaded. – Mike Grassotti May 29 '13 at 16:46
  • You forgot to `return` in the route's model. Promises won't be honored unless they're returned. – Mars May 26 '14 at 17:52
  • @MikeGrassotti if it's more than one model, it would probably be beneficial to wrap it in an `Ember.RSVP.hash`, wouldn't it? – Tom Doe Mar 05 '15 at 01:01
  • @TomDoe sure that works too, depends on how you are looking up the models. Probably the way to look at it is not the number of models but the number of async queries. For example I will use `Ember.RSVP.hash when I need to return arrays (recentlyAdded, Incomplete, etc.) of the same model. So if you are calling `find()` more than once... – Mike Grassotti Mar 05 '15 at 04:44
2

What you call cache is the content of the store. There are usually 2 ways to update the store to reflect changes made on the backend side:

  • the change happens with a user interaction/call to the server. If you update mulitple records on the backend side, you can sideload them with the response of that request.
  • the change happens asynchronously on the backend side (background job). You can use a websocket to push those changes to the client.
Cyril Fluck
  • 1,561
  • 7
  • 9