How to access app object in a route in Ember CLI or pass a value from an initializer to a route?


#1

I’m trying to migrate my app to Ember CLI and it’s pretty painful :smile:

In my current app I’m creating an app object and assign it to a global variable. When loading the app I do some checks and if any of them fails, I’m adding an error property to the app object that’s later checked in a route to eventually render error route.

Here’s the code:

window.ShareDrop.App = Ember.Application.create();
ShareDrop.App.deferReadiness();

checkStuff()
.then(checkOtherStuff)
.catch(function (error) {
    ShareDrop.App.error = error;
})
.then(function () {
    ShareDrop.App.advanceReadiness();
});

ShareDrop.App.IndexRoute = Ember.Route.extend({
    beforeModel: function() {
        if (ShareDrop.App.error) {
            throw new Error(ShareDrop.App.error);
        }
    }
};

ShareDrop.App.ErrorRoute = Ember.Route.extend({
    renderTemplate: function(controller, error) {
        var name = 'errors/' + error.message,
            template = Ember.TEMPLATES[name];
        if (template) this.render(name);
    }
});

I guess it’s not the most Ember-way to handle such things, but it works. In Ember CLI app I no longer have access to global app object and I have no idea how to pass an error from an initializer (I moved all the checkStuff().then... to an initializer) to a route.


#2

There seems to be an addon for that. https://github.com/ember-cli/ember-export-application-global. Ember-CLI used to export a global that was named like your app but that got removed some months ago.

You can of course also create a global variable in the apps init hook but I guess the addon is a cleaner way.

see https://github.com/ember-cli/ember-cli/pull/2183 for further discussion on this topic

edit after looking into this the addon I referenced seems to be included by default since some time.


#3

Thanks! Just had to add ENV.exportApplicationGlobal = true; to config/environment.js.

I’m just wondering what’s the best way to handle such case, i.e. how to make an error in an initializer trigger error route without using global variables to pass the error object.


#4

What are you doing in the initializer that might trigger an error? I’d suggest moving all async stuff (I suppose you are doing something async that might trigger errors) in initializers into the beforeModel hook of the application-route. Then you will geht the loading route and error route behaviour for free without the need for any workarounds.


#5

Thanks, but won’t it actually run it every time I change a route? I’d prefer to run it only once - I check for WebRTC support, try to clear local filesystem that may fail if browser is in private/incognito mode (via Filesystem API if it’s supported) and authenticate to Firebase. The first two could run every time a route is changed, but I’d prefer to authenticate to Firebase only once…

It doesn’t make much sense to authenticate to Firebase if user’s browser doesn’t support WebRTC and that’s why I put everything into initializer.