So I am trying to update my menu when a user logs in. I have read several answers about similar problems, but I still can't get it to work.
nav-bar.component.html:
<li *ngIf="isLoggedIn"><a routerLink="/" (click)="logout($event);"> {{ logoutLabel }}</a></li>
<li *ngIf="!isLoggedIn"><a routerLink="/login (click)="showPopup($event);">{{ loginLabel }}</a></li>
In nav-bar.component.ts I open a modal with the login-form and also look for changes in a variable from login.service
import { SuPopupLoginComponent } from '../shared/su-popup-login/su-popup-login.component';
import { LoginService } from '../login/login.service';
...imports...
@Component({
selector: 'app-nav-bar',
templateUrl: './nav-bar.component.html',
styleUrls: ['./nav-bar.component.scss']
})
export class NavBarComponent implements OnInit {
loginLabel: string;
public isLoggedIn: boolean;
constructor(private loginService: LoginService, private suPopupLoginComponent: SuPopupLoginComponent) {
loginService.getIsLoggedIn.subscribe((bool: boolean) => {
this.isLoggedIn = bool;
console.log('NavBarComponent', this.isLoggedIn);
});
}
showPopup(event) {
event.preventDefault();
this.suPopupLoginComponent.showPopup();
If I call login here It works just as expected
// this.loginService.login('[email protected]', 'Test123')
// .subscribe(
// data => {
// if (data) { // If login was successful data is true.
// let redirect = 'license-overview';
// this.router.navigate([redirect]);
// }
// }
// );
}
logout(event) {
event.preventDefault();
this.loginService.logout();
}
ngOnInit() { }
}
su-popup-login.component.ts - login-form and call to login function:
import { LoginService } from '../../login/login.service';
import { Injector } from '@angular/core';
@Component({
selector: 'su-popup-login',
templateUrl: './su-popup-login.component.html',
styleUrls: ['./su-popup-login.component.scss'],
providers: [LoginService]
})
export class SuPopupLoginComponent implements OnInit {
constructor(private loginService: LoginService, private injector: Injector) { }
public showPopup() {
Css and showing modal
}
login(event, mail, password) {
this.loginService.login(mail, password)
.subscribe(
data => {
if (data) { // If login was successful data is true.
// Navigate to view after login success.
this.router = this.injector.get(Router);
let redirect = 'license-overview';
this.router.navigate([redirect]);
}
}
);
}
login.service.ts
import { Injectable } from '@angular/core';
import { Http, Headers, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
@Injectable()
export class LoginService {
private isLoggedInSource = new BehaviorSubject<boolean>(localStorage.getItem('currentUser') ? true : false);
public _isLoggedIn: Observable<boolean> = this.isLoggedInSource.asObservable();
constructor(private http: Http) { }
private isLoggedIn(logged: boolean) {
this.isLoggedInSource.next(logged);
}
get getIsLoggedIn() {
return this._isLoggedIn;
}
login = (mail: string, password: string): Observable<boolean> => {
let loginUrl = '/api/authenticate';
let body = JSON.stringify({ mail, password });
return this.http.post(loginUrl, body)
.map((response: Response) => {
let user = response.json();
if (user && user.tokenId) {
this.isLoggedIn(true);
// Add to local storage
localStorage.setItem('currentUser', JSON.stringify({ mail: mail, tokenId: user.tokenId }));
return true; // Login success
}
else {
return false; // Login failed
}
});
}
}
It works fine if I call this.loginService.login('user', 'pass') from nav-bar.component, but not when login is called from su-popup-login.component.ts. Also, the this.loginService.logout() from nav-bar.component.ts works fine.
Does the subscribe call have to be in the same component as the calls to login/logout? If so, I guess I just don't understand how Observables work.
Thankful for any help or comments.
providers: [LoginService] in su-popup-login.component.ts created different instance of LoginService.
To make it work, you have to make sure that both components share single instance of LoginService
To avoid that use providers: [LoginService] in your ngModule of appcomponent or coremodule and remove providers: [LoginService] from su-popup-login.component.ts
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With