Ember observer when session is active on page load - ember.js

I am writing a EmberJS web application. I have a piece of code which should run only when the page has completed loaded and the session authentication is complete.
I tried setting an observer on session.isAuthenticated but it does not seem to be working.
Any thoughts?
Thanks

You can use didTransition hook of the particular route. You need to define it in actions hash, and dont forget to return true for bubbling to the parent route.
Inside didTransition hook, if you want to run some thing after the page has been rendered, then you can try,
Ember.run.schedule("afterRender",() => {
//you code
});

Related

How to create a controller property that updates when a service property changes

Using Ember 1.13
I may be missing something and going about this in the totally wrong way.
I have session state saved in an ember service that is available to all my controllers. It has a boolean property isExistingSession.
In the header of my app I want to conditionally display a login button or user info depending on the value of isExistingSession.
As far as I know I can't use the service property directly in my handlebar so my solution was to create a computed property on the applicationController that always equals the value of of isExistingSession on the sessionService
export default Ember.Controller.extend({
isExistingSession: function () {
return sessionService.get('isExistingSession');
}.property('sessionService.isExistingSession'),
But the computing the property off of an outside entity seems to be invalid.
Any idea on how to accomplish this?
As far as I know I can't use the service property directly in my handlebar
Just to clarify: any property available in a given controller will be available in its associated template. So if you inject your session service in your application controller you should be able to use any property of that service in your application.hbs template.
Now to solve your issue: how do you inject the service in your controller? You have 2 alternatives:
application.inject('controller', 'sessionService', 'service:session'); This will inject your session service in all the controllers, making in available to all your templates as well. (see http://guides.emberjs.com/v1.10.0/understanding-ember/dependency-injection-and-service-lookup/)
sessionService: Ember.inject.service('session'), This will inject your session service in a single controller (see http://emberjs.com/api/classes/Ember.inject.html#method_service)
Bottom line is that you should not need a computed property. I'd recommend using the Ember inspector to check whether your session is properly injected in your controller.
Also, consider using ember-simple-auth, an awesome add-on to manage authentication in Ember.

How should I handle page refreshes in EmberJS?

As I understand from the EmberJS Guide to Routing, you should specify the model you want a route to load in the Route's model hook. The model hook may return a promise, and if it does, the route will pause until the promise resolves.
Therein lies my problem: this approach works fantastically under normal use cases (user triggers a transition from any other route into the route in question.) The problem arises if the user is currently at the route in question.
If the user triggers a page refresh (using the browser's refresh button, or ctrl+r or whatever other trigger there might be, the promise in the model hook causes the user to sit at a blank white page until that promise returns. In large dataset cases, this can be a handful of seconds, which does not make for a great user experience.
So, how do I resolve this issue?
The only solution I have developed is to trigger the data load in the route's activate hook, and manually set the controller's model when that promise returns. I don't like doing this, because I'm circumventing the entirety of Ember's model framework.
I would like the application template to render before the model hook hangs the page, at a bare minimum. Any guidance on how to resolve this would be greatly appreciated.
In case the context is necessary: as the tags imply, I am using Ember-Data. I'm utilizing the RESTAdapter almost entirely out-of-the-box, unmodified.
Routes have sub-states that can be used to render a temporary template while the model is loading. See: http://guides.emberjs.com/v1.10.0/routing/loading-and-error-substates/
The first load/initial blank page is a UX problem that will be solved by Fast Boot, see: http://emberjs.com/blog/2014/12/22/inside-fastboot-the-road-to-server-side-rendering.html
Fast boot is already available through one of Ember's branches, I don't know the name.

How to handle loading events in controllers in ember

What is a good way to show a reusable loading screen whilst controllers are performing time consuming actions such as server queries. Ember provides shared loading route functionality for route transitions perhaps someone has been able to leverage these in controllers as well?
My current thinking is to implement actions in the ApplicationController to show and hide a loading div. Controllers can then call these before and after time consuming actions. Perhaps someone has a better solution?
I believe you have a few options. I would do one of these two:
Define a loading route/template. The loading template will be rendered into the outlet of the parent route and will be replaced by the current route's contents when the transition is complete. I did this once where I used a modal dialog to display a loading message.
Define actions in ApplicationRoute. Actions bubble from a controller, to the matching route, then up the route chain. If you define actions in the topmost route, you can send a message from any controller that will be caught. I currently have startLoading and stopLoading actions in my ApplicationRoute.

beforeModel not triggered on all transitions?

I need a systematic redirection to a login page when user is not authenticated. For that purpose, beforeModel in the application route seemed to be the best option, but it seems that beforeModel is not triggered for all transitions, unlike willTransition, which is always called, but when the route is exited, not entered...
For instance, beforeModel is not called when changing the URL manually.
I've read this Gist which explains that willTransition is always called, which I confirm, but it doesn't explain if beforeModel should always be called or not, and in which conditions.
I'm using Ember 1.2.0 beta 3 but I have the same problem with 1.1.2 and login redirection is actually handled by ember-simple-auth (my issue on the repo: #27).
Could someone explain when should beforeModel be called ?
Note : I've asked the same question on Ember Discuss but had no answer.
I'm on 1.1.0-beta.4 and beforeModel works fine. beforeModel should be called in any case like URL change or a transition with a model (e.g. via link-to). The model hook is skipper if we use link-to or transition from a controller.
To get more info and help with debugging set LOG_TRANSITIONS
App = Ember.Application.create({
LOG_TRANSITIONS: true
});

Delaying route change until data is loaded in Ember

In Angular the $routeProvider resolve property allows delaying of route change until data is loaded. Given the route model hook in Ember returns a promise I was wondering how that stuff was done in Ember
Here it's what I mean in angular Delaying AngularJS route change until model loaded to prevent flicker
A link with a sample code would be great
Just recently this PR introduced Async transitions to ember.js. With this change you can do all sort of things, like for example delaying a route's transition if data is still underway. A route has now all sorts of hooks available to do just want you want.
As an example (taken from the gist mentioned below) in the afterModel hook you could do something like this to only transition to the post.show route if you actually have data:
App.PostsIndexRoute = Ember.Route.extend({
afterModel: function(posts, transition) {
if (posts.length === 1) {
this.transitionTo('post.show', posts[0]);
}
}
});
Since this new features are still very young you need to use the latest master to have it available. For more info on how to use the API please see this gist.
Hope it helps