Guard
Guard

Reputation: 6955

Ember: a place for common property?

I' writing a hybrid app with a bit of server processing and main UI part implemented with Ember.

All auth-related functionality is server-based, so when the page loads I already know (based on cookies) if the user is authenticated or not.

In short - on the client-side I have a userId cookie, if it's set then the user is authenticated.

Now I need to make this data available to all templates.

I solved it for the application template (all code in CoffeeScript, but nothing special about the language there):

route

ApplicationRoute = Ember.Route.extend
  setupController: (controller) ->
    userId = jQuery.cookie 'userId'
    if userId == 'undefined'
      userId = null
    else
      userId = parseInt userId, 10
    controller.set 'userId', userId

controller

ApplicationController = Ember.Controller.extend
  userId: null

finally, the template

<strong>
  {{#if userId}}
    userId: {{userId}}
  {{else}}
    No user
  {{/if}}
</strong>

This works from the application template, but if I move it to, say, index template, it always says 'no user' (I expected some prototypal chain traversing for controllers).

I tried moving it to boud helper - doesn't work as well, the helper is not being called at all:

Ember.Handlebars.registerBoundHelper 'userId', ->
  userId = jQuery.cookie 'userId'
  if userId == 'undefined'
    userId = null
  else
    userId = parseInt userId, 10
  userId

Upvotes: 1

Views: 491

Answers (1)

CraigTeegarden
CraigTeegarden

Reputation: 8251

I've used App.deferReadiness() and App.advanceReadiness() combined with setting the global properties directly on the App to handle that situation. deferReadiness() keeps ember from initializing and advanceReadiness() lets ember finish initializing.

From the ember api for deferReadiness():

Use this to defer readiness until some condition is true.

Example:

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

   jQuery.getJSON("/auth-token", function(token) {
     App.token = token;
     App.advanceReadiness();
   });

This allows you to perform asynchronous setup logic and defer booting your application until the setup has finished.

For example, you can use this to grab the user's id from the cookie before initializing ember, and store it in App.currentUser:

App = Ember.Application.create({});

App.deferReadiness();

var userId = "1234";//jQuery.cookie 'userId'
if (userId == 'undefined') {
  userId = null;
  App.set('currentUserLoggedIn', false);
  //window.location = "/login"; // redirect to login page
} else {
  userId = parseInt(userId, 10);
  App.set('currentUserLoggedIn', true);
  App.set('currentUser', userId);
  App.advanceReadiness();
}

You can then access this anywhere in your app using:

App.get('currentUser');

or in templates:

{{App.currentUser}}

JSBin example

Upvotes: 1

Related Questions