Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Waiting for models to load before rendering app in Ember.js

I have a number of different application-level models — i.e., current user, current account, etc. — that I want to load before rendering my application. How and where should this be done? This question/answer helped a lot, but it doesn't cover the async aspect.

The following code accomplishes what I want, but loading the models in beforeModel (to take advantage of it waiting for the promise to resolve) doesn't seem right. Should I even be loading these models in ApplicationRoute?

App.ApplicationController = Ember.Controller.extend({
  currentAccount: null
});

App.ApplicationRoute = Ember.Route.extend({
  beforeModel: function () {
    var self = this;

    return App.Account.find(...).then(function (account) {
      self.controllerFor('application').set('currentAccount', account);
    });
  }
});

Thanks for your help!

like image 938
Justin Stayton Avatar asked Aug 07 '13 13:08

Justin Stayton


People also ask

Is Ember js still popular?

6.3% of javascript developers are currently using Ember. Its popularity has stagnated over the last few years. Ranked 4rd most popular front-end JavaScript framework in State Of JS survey. Github – 20k stars, 4k forks and 750 contributors.

What is model in Ember js?

In Ember Data, models are objects that represent the underlying data that your application presents to the user. Note that Ember Data models are a different concept than the model method on Routes, although they share the same name.

Is Ember a library or framework?

Ember. js is a productive, battle-tested JavaScript framework for building modern web applications. It includes everything you need to build rich UIs that work on any device.

Is Ember js frontend or backend?

It should also be mentioned that Ember is purely a frontend framework. It has a number of ways of interacting with the backend of your choice, but this backend is not in any way handled by Ember itself.


Video Answer


1 Answers

The trick is to return a promise from the route's model method.
This will cause the router to transition into App.LoadingRoute route, until the promise resolves (which can be used for loading indication bars/wheels etc.)
When the promise resolves, the App.LoadingRoute will be deactivated, and the original route's setupController method will be called.
This works for ember-data promises, JQuery's $.ajax promises and ember-model's fetch promises.
Just make sure you return the actual model after resolving the promise.
This can also be a good place to handle errors if the promise is rejected - but I'll leave that to some other question.

As for where you should load your models - that is dependent on your app's usage.
Usually you would load a model where the URL indicates you need that model - a rule of thumb would be the indication of a model ID in the URL.
This of course changes if you need to prefetch some data.

And now for some code:

App.SomeRoute = Ember.Route.extend({
   model: function(params){
       return App.SomeModel.fetch(params.model_id).then(function(modelData){
           // it is better to return the actual model here, and not the promise itself
           return App.SomeModel.find(params.model_id);
       });

   },
   setupController: function(controller, model){
       controller.set("model", model);
       // do some controller setup here - can be omitted if no setup is needed
       // this will run only after the promise has been resolved.
   }
});

App.LoadingRoute = Ember.Route.extend({
        activate: function(){
            this._super();
            // add some loading indication here
        },
        deactivate: function(){
            this._super();
            // remove loading indication
        }
}

Hope this helps.

like image 159
Meori Oransky Avatar answered Oct 29 '22 00:10

Meori Oransky