Reputation: 761
I have a strange situation. I have nav component which I want to show only when the user is logged in. I am trying to manage that using a variable which is false by default and when a user logs in, the value is true and menu is visible.
the current situation is that, when a user clicks on the logout link on the MenuComponent, the event is emitted and the value changes. But on login, after the http response, it is not getting triggered.
Here is the menu component:
import { Component, OnInit } from '@angular/core';
import { UserService } from './../user/user.service';
import { Router } from '@angular/router';
@Component({
moduleId: module.id,
selector: 'app-navigation',
templateUrl: 'navigation.component.html',
styleUrls: ['navigation.component.css'],
providers: [UserService]
})
export class NavigationComponent implements OnInit {
public menuStatus;
constructor(private userService: UserService, private router: Router) {
this.menuStatus = userService.isLoggedIn();
}
ngOnInit() {
this.userService.userLoggedOut$.subscribe(data => {
console.log('userLoggedOut subscribe');
this.menuStatus = data;
});
this.userService.userLoggedIn$.subscribe(data => {
console.log('userLoggedIn subscribe');
this.menuStatus = data;
});
}
logout() {
this.userService.userLogout();
this.router.navigate(['/login']);
}
}
In this, the logout button click triggers logout function. The user service userLogout function has the event emitter. Here is the event emitter:
import {Injectable} from '@angular/core';
import { Headers, Http } from '@angular/http';
import 'rxjs/add/operator/toPromise';
import { Subject } from 'rxjs/Subject';
import { Config } from './../shared/config';
@Injectable()
export class UserService {
private loggedIn;
private userLoginUpURL;
private userLoggedInEvent = new Subject();
private userLoggedOutEvent = new Subject();
userLoggedIn$ = this.userLoggedInEvent.asObservable();
userLoggedOut$ = this.userLoggedOutEvent.asObservable();
constructor(private http: Http, private config: Config) {
this.loggedIn = false;
this.loggedIn = !!localStorage.getItem('access_token');
this.userLoginUpURL = this.config.loginUrl;
}
getUserObject() {
return JSON.parse(localStorage.getItem('user_object'));
}
userLogin(userLoginDetails) {
let headers = new Headers({
'Content-Type': 'application/json'
});
let postData = {
email: userLoginDetails.email,
password: userLoginDetails.password
};
return this.http
.post(this.userLoginUpURL, JSON.stringify(postData), {headers: headers})
.toPromise()
.then(res => {
localStorage.setItem('access_token', res.json().access_token.access_token);
localStorage.setItem('user_object', JSON.stringify(res.json().user));
this.loggedIn = true;
this.userLoggedInEvent.next(this.loggedIn);
return res.json();
})
.catch(this.handleError);
}
userLogout() {
// destroy the local storage variabled
localStorage.removeItem('access_token');
localStorage.removeItem('user_object');
// setup the login status to false
this.loggedIn = false;
this.userLoggedOutEvent.next(false);
}
isLoggedIn() {
return this.loggedIn;
}
private handleError(error: any) {
return Promise.reject(error.message || error);
}
}
Problem is, after logging in when I am calling this.userLoggedInEvent.next(this.loggedIn), the event doesn't fire.
Can someone please help. There is any easy fix where I can refresh the window and redirect the user to the Dashboard, but I don't want to refresh the page and do it the correct way. Please help.
Upvotes: 1
Views: 240
Reputation: 657406
Ensure you provide UserService
only once on a common parent (root component) otherwise different components will get different instances and listening on one instance while emitting on another won't achieve much ;-)
Upvotes: 1