Im facing an issue with angular.
I have an authService which i am using through all of my components, I am using a Subject which i can subscribe to in my components if i need to check that the user is logged in, The issue i am facing is this works fine if i directly load the page that will be using it, But not when i go through a route.
So i load http://localhost:4200/testing which is this component
import { Component, OnInit } from '@angular/core';
import {AuthenticationService} from "../../services/authentication.service";
@Component({
selector: 'app-testing',
templateUrl: './testing.component.html',
styleUrls: ['./testing.component.css']
})
export class TestingComponent implements OnInit {
loggedIn: boolean = false;
constructor(private authService: AuthenticationService) { }
ngOnInit() {
this.authService.getLoginStatus().subscribe(loginStatus => this.loggedIn = loginStatus);
}
}
All this code does is subscribe to the authService Subject which can be seen below
import {Injectable} from '@angular/core';
import {HttpClient} from "@angular/common/http";
import {environment} from "../../environments/environment";
import 'rxjs/add/operator/map'
import {UserService} from "./user.service";
import {Subject} from "rxjs/Subject";
import {Subscription} from "rxjs/Subscription";
@Injectable()
export class AuthenticationService {
private isLoggedIn = new Subject<boolean>();
private apiUrl = environment.apiUrl + 'login/';
private deleteSubscribe: Subscription;
constructor(private http: HttpClient,
private userService: UserService) {
this.isLoggedIn.next(false);
}
login(username: string, password: string) {
return this.http.post<any>(this.apiUrl + '?' + environment.apiDebug, {
username: username,
password: password
}).map(user => {
// Login success if there is a JWT token in the
if (user.loginSucess && user.token) {
// Store the user details and JWT token in the local storage to keep the user logged in between page refreshes
localStorage.setItem('currentUser', user.token);
// Grab the user data then set logged in equal to true
this.userService.getAccountDetails().subscribe(userData => {
this.isLoggedIn.next(true);
});
}
return user;
});
}
checkLoginStatus() {
if (localStorage.getItem('currentUser')) {
return this.http.get<any>(this.apiUrl + 'check_login')
.map(loginStatusReturn => {
if (loginStatusReturn.isLoggedIn === true) {
this.isLoggedIn.next(true);
this.userService.getAccountDetails().subscribe();
return true;
} else {
// Delete the local stored cookie, It was invalid
localStorage.removeItem('currentUser');
this.isLoggedIn.next(false);
this.userService.clearUserInfo();
return false;
}
})
}
}
logout() {
// Remove user from the local storage
this.deleteSubscribe = this.http.delete(this.apiUrl + 'logout?').subscribe();
localStorage.removeItem('currentUser');
this.userService.clearUserInfo();
this.isLoggedIn.next(false);
this.deleteSubscribe.unsubscribe();
}
getLoginStatus() {
return this.isLoggedIn.asObservable();
}
}
When i load the page directly i see that the loginStatus in the testing component is set to true and all is well, If i then click to another page and then click the router link back to the testing page the code in the subscribe block never gets ran and the login status stays at false
I have the service imported in my app.module.ts under providers
I am at the stage of banging my head on the desk with this one
Any help would be much appreciated
Cheers
Your subject (isLoggedIn
) probably needs to be a ReplaySubject
. A ReplaySubject
will re-emit the last value to all new subscribers. As it stands now, when your second component subscribes it will not receive an event.
It looks like this service is provided in your app module, meaning that it will only be initialized once (when the app first loads). As a result, this.isLoggedIn.next(false)
in your constructor will only fire once -- potentially before your new component is initialized.