I am trying to implement a nav bar that displays either Sign in
or Sign out
depending on a boolean value in an Ember Service that I have injected into the application
route (defined in routes/application.js
).
I also read this and it reaffirms my choice of the service approach of handling state.
Now the question and problem is that the child components are not updating when I redirect from one route to another. If the link says Sign in
, when I successfully authenticate and sign in, the link will still say Sign in
. It's only when I refresh the page does the link text change to Sign out
. The Sign out
link behavior is the same.
Code in application.hbs
:
{{nav-bar isAuthenticated=isAuthenticated}} ==> seems like only loaded once
{{outlet}}
Code for the sign-in and sign-out links in nav-bar.hbs
:
{{log isAuthenticated }} ==> only prints upon page load, doesn't print on route changes
{{#if isAuthenticated}}
<ul class="nav navbar-nav navbar-right">
{{#link-to 'logout' tagName="li" class="nav-item"}}<a class="nav-link" href="">Logout</a>{{/link-to}}
</ul>
{{else}}
<ul class="nav navbar-nav navbar-right">
{{#link-to 'login' tagName="li" class="nav-item"}}<a class="nav-link" href="">Login</a>{{/link-to}}
</ul>
{{/if}}
My log-in action:
this.transitionTo('dashboard');
Problem is that it transitions without updating the nav bar. Why is that? What can I do to run around this problem?
Update regarding comments and first answer:
What if I don't have an application controller? I have this so far in my application Route but it's still not updating even though I'm passing the data down to the nav bar component:
simpleAuthManager: Ember.inject.service(),
isAuthenticated: Ember.computed('simpleAuthManager', 'simpleAuthManager.user', function() {
console.log(this.get('simpleAuthManager.user'));
return this.get('simpleAuthManager').isAuthenticated();
}),
setupController(controller, model) {
this._super(controller, model);
controller.set('isAuthenticated', this.get('isAuthenticated'));
}
A computed property is required to recompute the state every time isAuthenticated
changes.
As I understand, you have a nav-bar child component present in your application template and have a service that manages the current logged-in/logged-out state of your application. Computed properties along with service injection can help you here.
Set up a computed property that watches your isAuthenticated
variable from your service in your application controller (make a controller if you haven't). Pass the isAuthenticated
as a parameter to your nav-bar component. In the nav-bar component inject the service as well, and have it set the authenticated state in an action every time a log-in/log-out link is clicked.
This way each time someone logs in or out your service is updated and as a consequence so is your isAuthenticated
computed property in your application controller.
You can read up on Ember's computed properties here.