Ember how to update isAuthenticated after logging in - ember.js

I have an app setup using ember-cli 0.1.1 and I'm using ember-simple-auth (along with devise cli plugin) for login. In my application template, I have a menu with a conditional wrapped around it:
{{#if session.isAuthenticated }}
<div class="nav_user">
<p>{{session.user_name}}</p>
<p class="user_account">{{#link-to 'account-settings'}}<img src="assets/images/gear.png" />{{/link-to}}</p>
</div>
<ul>
<li>{{#link-to 'horses'}}My Horses{{/link-to}}</li>
<li>{{#link-to 'veterinarians'}}Veterinarians{{/link-to}}</li>
<li>{{#link-to 'documents'}}Documents{{/link-to}}</li>
<li>{{#link-to 'notes'}}Notes{{/link-to}}</li>
</ul>
<ul>
<li><a {{action 'invalidateSession'}}>Logout</a></li>
</ul>
{{/if}}
The problem is that after a successful login, I transition to another route and if I immediately open the menu, the non-authenticated menu is what appears. If I refresh, then I get the correct menu contents. I'm looking for a way to updat session.isAuthenticated after a successful login, prior to transitioning to the new route. Thanks in advance for any help.

Related

ember element that is hidden by focus out event is blocking click event

I have an odd conundrum.
It appears that when an element is hidden by a focus-out event ember is unable to attach the corresponding click event that triggered the focus out properly. For example with the code below if the <a> tag triggers the focus-out event on the input and the code behind turns _focused to false then the selectOpts event is never triggered. It appears to only happen if the a tag is hidden as a result of the focus-out.
Also oddly it does not matter how the a tag is hidden either if i do just display:none it still also doesn't fire the selectOpt action.
Here is my code:
<div class="dropdown">
{{input value=value class='form-control' focus-in="focused" focus-out="unfocused" }}
{{#if _focused}}
<ul class='dropdown-menu'>
{{#each _filteredOptions as |opt|}}
<li><a href="#" {{action "selectOpt" opt}}>{{opt}}</a></li>
{{/each}}
</ul>
{{/if}}
</div>
Here is a ember twilldle showing the issue.
https://ember-twiddle.com/6bbdb669d19d7a498e645bb0297f1b46?openFiles=templates.components.input-autocomplete.hbs%2Ctemplates.components.input-autocomplete.hbs
In order to get it to show the issue focus in on the text area and then try to select one of the links that appear below the input. What is supposed to happen is that when you select the link it is to populate the input field with the value.
You can use just focus-in instead of both focus-in and focus-out. So when you click on input focus-in event trigger and set _focused to true. Then, in action selectOpt you set value and after that set property _focused to false.
<div class="dropdown">
{{input value=value class='form-control' focus-in='focused' }}
{{#if _focused}}
<ul class='dropdown-menu'>
{{#each options as |opt|}}
<li>
<a href="#" {{action "selectOpt" opt}}>{{opt}}</a>
</li>
{{/each}}
</ul>
{{/if}}
input-autocomplete.js
actions: {
focused() {
this.set('_focused', true);
},
selectOpt(opt) {
console.log(opt);
this.set('value', opt);
this.set('_focused', false);
}
}
I didn't include all code for input-autocomplete it's the same as before exxept actions. Also I used options array insted your filter because didn't get any results when clicked on input.

Display dynamic content in Ember application template

I am creating an Ember app that manages a list projects and tasks for each project. In the app's navigation, I want to display the name of the selected project. If someone navigates to /projects/1/tasks, I want the page to display project 1's title, along with links to pages specific to that project. Here is what I have started for my application.hbs file of how I expected it to work, however the project title is blank and the links don't work:
<nav id="nav-menu">
<ul>
<li class='menu-project-title'>
{{#link-to 'projects'}}{{project.title}}{{/link-to}}
</li>
<li class='menu-separator'> </li>
<li>{{#link-to 'projects.tasks' project}}Tasks{{/link-to}}</li>
<li>{{#link-to 'projects.people' project}}People{{/link-to}}</li>
</ul>
</nav>
<div class="container" id='main-outlet'>
{{outlet}}
</div>
If I know every route will always have a project returned, what is the best way to pass that data into the application template?
You could use an Ember.computed.readOnly property in your application controller.
App.ApplicationController = Ember.Controller.extend({
needs: ['project'],
activeProject: Ember.computed.readOnly('controllers.project.model')
...
});
But maybe this isn't the best solution. As far as I understand it, the project route/template is always used? So why not move everything to that template.

Does Handlebars evaluate null to true?

I require another controller in the application controller:
App.ApplicationController = Ember.Controller.extend({
needs: ['login'],
...
Then I try to use some of the properties of the login controller in the application template:
{{#if controllers.login.token}}
<li>
<a {{action logout}} href="#/">log out</a>
</li>
{{else}}
<li>
log in
</li>
{{/if}}
When I write {{log controllers.login.token}} directly over the #if I get null.
But the if branch is still shown, not the else branch.
null is falsey. Example: http://emberjs.jsbin.com/jivoqa/1/edit
{{log xyz}} is deceptive, it logs it when the page is being built, not necessarily what the value still is. You'd be better off doing {{xyz}} and just tossing it in the page to see what it is.

Ember.js: Toggle Nested Views

I have a header with some login/signup forms that popup when you click the respective buttons.
While it was working fine using just jQuery, I've now started to integrate Ember into the application and I'm running into some trouble with some simple toggle functionality.
Here's the basic HTML markup:
<header>
<h1>Page Title<h1>
<nav>
<a id="toggles-login" class="button {{active_class_binding}}">Login</a>
<a id="toggles-signup" class="button {{active_class_binding}}">Signup</a>
</nav>
<div id="popup-forms">
<div id="login-form"></div>
<div id="signup-form"></div>
</div>
<header>
I'm completely new to Ember and I really have no idea how to set this up. The only thing I want is to be able to set the popup forms up as Ember.View objects and toggle them with some action helpers.
I really am lost on this one.
A simple solution would be to trigger simple actions to show the respective forms:
<a id="toggles-login" class="button {{active_class_binding}}" {{action showLoginForm target="view"}}>Login</a>
<a id="toggles-signup" class="button {{active_class_binding}}" {{action showSignupForm target="view"}}>Signup</a>
The corresponding view would have to implement both actions:
App.YourView = Ember.View.extend({
showLoginForm : function(){
this.$("#login-form").toggle();
},
showSignupForm : function(){
this.$("#signup-form").toggle();
}
});

Change Navbar based on login state

I’ve been trying, using Rails/Ember pre-4, to do a fairly typical thing, that is have a page with a navbar and a content section. The navbar only changes on login (shows logout button when logged in and login and register buttons when logged out), not on every page change.
At first thought i could do something in the application.hbs template such as:
{{view navbar}}
{{outlet}}
where i set up navbar to respond to login state changes (managed by a state manager). This didn’t seem to work.
Then i tried something like (also in application.hbs):
{{outlet navbar}}
{{outlet}}
and tried setting navbar in each route, which results in lots of duplication and also didn’t ultimately work.
Before posting code, wanted to know if anyone already has a good solution to this common situation where certain parts of your page such as a navbar or sidebar only change upon some change in app state, not on every page change.
There are lots of ways to get this done. The first approach you described is closest to what we are doing. In past ember versions we used view helper for this, today we use {{render}} but it's the same basic concept. For example, application.hbs might look like this:
{{render navbar}} {{outlet}}
Now navbar.hbs can use a simple {{#if}} helper to swap links based on login state.
<div class="navbar">
<div class="navbar-inner">
{{#linkTo index class="brand"}}My App{{/linkTo}}
<ul class="nav">
<li>{{#linkTo index}}Home{{/linkTo}}</li>
<li>{{#linkTo about}}About{{/linkTo}}</a></li>
</ul>
<ul class="nav pull-right">
{{#if isAuthenticated}}
<li><a {{action logout}} href="#">Logout</a></li>
{{else}}
<li><a {{action login}} href="#">Login</a></li>
{{/if}}
</ul>
</div>
</div>
Now we add logic to NavbarController that tracks and manages login state.
App.NavbarController = Ember.ArrayController.extend({
isAuthenticated: false,
login: function() {
this.set('isAuthenticated', true);
},
logout: function() {
this.set('isAuthenticated', false);
}
});
In a real app NavbarController would proxy these requests to another controller, perhaps currentUserController. I've created a working sample here: http://jsbin.com/iyijaf/6/edit