Why is my Ember.js outlet failing to conditionally render sometimes?

651 Views Asked by At

I'm trying to implement a very basic login form. I have this:

<script type="text/x-handlebars" data-template-name="application">
    {{#if userIsLoggedIn}}
        {{outlet}}
    {{else}}
        {{partial "login"}}
    {{/if}}
</script>

<script type="text/x-handlebars" data-template-name="_login">
    <div>Username: {{input value=username type="text"}}</div>
    <div>Password: {{input value=password type="password"}}</div>
    <button {{action 'logIn'}}>l o g i n</button>
</script>

The logIn action updates userIsLoggedIn.

When this first loads, it shows the login form as expected.

When I log in, the login form disappears and normal stuff gets rendered into the outlet, as expected.

Someplace else I have a Log Out button that changes userIsLoggedIn to false. When I press this, the normal stuff disappears and the login form reappears, as expected.

At this point everything looks like it did on first loading. But if I then log in again, I get a blank page. Why?

I think maybe I'm not supposed to have an outlet inside an if block. But if I pull it out, I have to stop it from being used sometimes by copying the userIsLoggedIn check somewhere else. And I can't find a single place where I can put that duplicated check in order to produce the behavior I want. ApplicationRoute.renderTemplate() seems to be a natural place, but I tried many things and did not come up with any way to turn my whole outlet hierarchy (most of which is not shown above) on and off with just one login status check.

2

There are 2 best solutions below

2
On BEST ANSWER

Have you tried using a login route, and if they aren't logged in when they hit a route, you block the route, and retry it after they are logged in?

Info talking about new transitions and an example of how to do what I just said

0
On

J Quigley, take a look at this fiddle: http://jsfiddle.net/hjdivad/RBLMW/. I believe it's working the way you want.

I've tried to write up an explanation for why your fiddle fails, but I don't understand the internals of the new router well enough to be confident in my answer. I believe the tl;dr is something along the lines of:

Don't put {{outlet}} inside a conditional that can change within the current route.

The jsfiddle I offered replaces the conditional with a separate route, as Daniel had suggested. Basically the important point is to make sure that the route hierarchy that depends on a user being authenticated is separate from the login route hierarchy, to avoid accidentally skipping the check by having a cached route handler.