2

As a follow up to my another question (I think this one is more specific) I'd like to ask you how can I load data when an app starts. I need some cache strategy.

The data that is presented in our internal app is refreshed once a week so that I don't want to make a new request every time a user enters a route (now I see a lot of ajax requests moving around the app).

the .all() method would probably resolve my problem but first I have to load the data.

Where else can I load data that would be accessible to controller and then templates? Is it possible to load data when an app starts and pass it to a controller as you does with the model and controllerFor hooks?

In my opinion there's no problem that a user has to refresh the app once a week - maybe we can change that later.

my understanding of intuitivepixel answer

First load data from the server:

App = Ember.Application.create({
    ready: function() {
        this.set('userCache', App.User.find());
        this.set('currentUserCache', App.User.find(1));
        this.set('topCache', App.Top.find());
    }
});

Then load data from cache (store)

App.SomeRoute = Ember.Route.extend
  setupController: (controller, model) ->
    @controllerFor('user').set 'content', App.User.all()
    # though I can access its properties via console data is not visible in the template
    @controllerFor('currentUser').set 'content', App.User.all().objectAt(0)
    @controllerFor('top').set 'content', App.Top.all()

For example though I can access avatar source with:

App.CurrentUser.all().objectAt(0).get('gravatar')

it is not visible in the template

{{#linkTo 'users' classNames="avatar pull-left" title="back"}}
  {{avatar gravatar}}
{{/linkTo}}

I also tried with content.gravatar or controler.gravatar but to no success. The rest is visible in the view

Community
  • 1
  • 1
wryrych
  • 1,765
  • 4
  • 20
  • 31

1 Answers1

2

Only conceptually you could do something like this:

App = Ember.Application.create({
  // Load your data once and set it somewhere accessible
  ready: function() {
    this.set('superModelCache', App.SuperModel.find());
  }
});


// Define your special model
App.SuperModel = DS.Model.extend({
  prop1: DS.attr('string'),
  prop2: DS.attr('string'),
  ...
});

// And then in all the routes that need data from your cache
// you could do something like this
App.MyFirstRoute = Ember.Route.extend({
  model: function () {
    return App.get('superModelCache.prop1');
  }
});

// and so on...
App.MySecondRoute = Ember.Route.extend({
  model: function () {
    return App.get('superModelCache.prop2');
  }
});

Or you could then in your routes do also something like this:

// And then in all the routes that need data from your cache
// you could do something like this
App.MyFirstRoute = Ember.Route.extend({
  model: function () {
    return App.SuperModel.all().get('prop1');
  }
});

// and so on...
App.MySecondRoute = Ember.Route.extend({
  model: function () {
    return App.SuperModel.all().get('prop2');
  }
});

This would only issue a GET request on application start, then well you could reload your data with some intervall/polling along the application lifetime.

If your application relies on the data to start at all, you could also call App.deferReadiness(); and then his counterpart App.advanceReadiness(); when your done, see here the API docs for reference: http://emberjs.com/api/classes/Ember.Application.html#method_deferReadiness

Hope it helps

intuitivepixel
  • 23,302
  • 3
  • 57
  • 51
  • Sorry for the delay but I'll try to try it out as soon as I get back to my old ticket, ok? – wryrych May 17 '13 at 06:29
  • OK, two issues I need to resolve. #1 If I load a model via App.User.find(1) (current user) how can I loaded via all? all(1) does not seem to work. #2 you could show me how to use deferReadiness and advanceReadiness when you load more models? Is it possible with the ready hook? – wryrych May 17 '13 at 12:58
  • #1 `.all(1)` does not work, that's the reason why I proposed the simple approach to do `return App.get('superModelCache.prop1');` in your model hook(s) beeing `prop1` what you would get with `.find(1)` but without using the store. #2 `deferReadiness` and `advanceReadiness`, there is not much to it except that when you call `deferReadiness` ember will wait with the bootprocess until you called `advanceReadiness` – intuitivepixel May 17 '13 at 15:19
  • Hm, I don't quite understand. What's your SuperModel and what are .prop1 and .prop2? Please, take a look at my updated example to see my understanding. – wryrych May 20 '13 at 06:36
  • The `SuperModel` is only conceptual, you can call it whatever you want, and `prop1` etc. also, since I don't know your data I put somethng invented, makes sense? :) But looking at your updated question I think this line `this.set('currentUserCache', App.User.find(1));` should be rather something like `this.set('currentUserCache', App.User.all().objectAt(0));` otherwise the `currentUserCache` is not coming from the already loaded data `App.User.find()`. – intuitivepixel May 20 '13 at 12:30
  • I have at least two issues so I gave it up. #1 couldn't figure out how to load this one record and #2 Embers was issuing two requests in some cases: first: resource was not found and then it was. – wryrych May 21 '13 at 17:18