I am trying to create a login service that will keep track of whether a user is logged in or not. I have implemented a server which uses JWT’s and works correctly. I am now trying use my auth service/user service to drive aspects of the UI e.g show navigation menu items if the user is logged in or not. The issue I face is when the app is refreshed or rebuilt, it doesn’t seem to react to existing tokens stored in localstorage(this is a temporary solution whilst i build by app)
auth/user service
export class UserService {
public token?: Observable<UserToken>;
public isLoggedIn = (): Observable<boolean> =>
this.loggedInSubject.asObservable();
private loggedInSubject = new BehaviorSubject<boolean>(false);
private tokenSubject?: BehaviorSubject<UserToken>;
constructor(private router: Router, private http: HttpClient) {
const storedToken = localStorage.getItem('token');
this.tokenSubject = new BehaviorSubject<UserToken>({
token: storedToken || '',
this.token = this.tokenSubject?.asObservable();
login(user: Login): Observable<any> {
return this.http.post(`${environment.apiUrl}/login`, user).pipe(
this.loggedInSubject.next(true);
this.router.navigate(['/test']);
localStorage.removeItem('token');
this.tokenSubject?.next({ token: '' });
this.router.navigate(['/login']);
register(user: SignUp): Observable<any> {
return this.http.post(`${environment.apiUrl}/register`, user).pipe(
public get tokenValue(): UserToken {
return this.tokenSubject?.value ?? { token: '' };
private saveToken(token: UserToken) {
console.log('token', token);
localStorage.setItem('token', token.token);
this.tokenSubject?.next(token);
<code>@Injectable({
providedIn: 'root',
})
export class UserService {
public token?: Observable<UserToken>;
public isLoggedIn = (): Observable<boolean> =>
this.loggedInSubject.asObservable();
private loggedInSubject = new BehaviorSubject<boolean>(false);
private tokenSubject?: BehaviorSubject<UserToken>;
constructor(private router: Router, private http: HttpClient) {
const storedToken = localStorage.getItem('token');
this.tokenSubject = new BehaviorSubject<UserToken>({
token: storedToken || '',
});
this.token = this.tokenSubject?.asObservable();
}
login(user: Login): Observable<any> {
return this.http.post(`${environment.apiUrl}/login`, user).pipe(
map((token: any) => {
this.saveToken(token);
this.loggedInSubject.next(true);
this.router.navigate(['/test']);
return token;
})
);
}
logout() {
localStorage.removeItem('token');
this.tokenSubject?.next({ token: '' });
this.router.navigate(['/login']);
}
register(user: SignUp): Observable<any> {
return this.http.post(`${environment.apiUrl}/register`, user).pipe(
map((token: any) => {
this.saveToken(token);
return token;
})
);
}
public get tokenValue(): UserToken {
return this.tokenSubject?.value ?? { token: '' };
}
private saveToken(token: UserToken) {
console.log('token', token);
localStorage.setItem('token', token.token);
this.tokenSubject?.next(token);
}
}
</code>
@Injectable({
providedIn: 'root',
})
export class UserService {
public token?: Observable<UserToken>;
public isLoggedIn = (): Observable<boolean> =>
this.loggedInSubject.asObservable();
private loggedInSubject = new BehaviorSubject<boolean>(false);
private tokenSubject?: BehaviorSubject<UserToken>;
constructor(private router: Router, private http: HttpClient) {
const storedToken = localStorage.getItem('token');
this.tokenSubject = new BehaviorSubject<UserToken>({
token: storedToken || '',
});
this.token = this.tokenSubject?.asObservable();
}
login(user: Login): Observable<any> {
return this.http.post(`${environment.apiUrl}/login`, user).pipe(
map((token: any) => {
this.saveToken(token);
this.loggedInSubject.next(true);
this.router.navigate(['/test']);
return token;
})
);
}
logout() {
localStorage.removeItem('token');
this.tokenSubject?.next({ token: '' });
this.router.navigate(['/login']);
}
register(user: SignUp): Observable<any> {
return this.http.post(`${environment.apiUrl}/register`, user).pipe(
map((token: any) => {
this.saveToken(token);
return token;
})
);
}
public get tokenValue(): UserToken {
return this.tokenSubject?.value ?? { token: '' };
}
private saveToken(token: UserToken) {
console.log('token', token);
localStorage.setItem('token', token.token);
this.tokenSubject?.next(token);
}
}
From this service – I use the
<code> public isLoggedIn = (): Observable<boolean> =>
this.loggedInSubject.asObservable();
<code> public isLoggedIn = (): Observable<boolean> =>
this.loggedInSubject.asObservable();
</code>
public isLoggedIn = (): Observable<boolean> =>
this.loggedInSubject.asObservable();
in my component e.g the nav component
<code> @if(!(isLoggedIn$ | async) ){
<li routerLink="/signup" routerLinkActive="['active']">
<li routerLink="/login"><a>Login</a></li>
<li routerLink="/create-match"><a>Create Match</a></li>
<li (click)="logout()"><a>Log out</a></li>
<code> @if(!(isLoggedIn$ | async) ){
<li routerLink="/signup" routerLinkActive="['active']">
<a>Sign Up</a>
</li>
<li routerLink="/login"><a>Login</a></li>
} @else {
<li routerLink="/create-match"><a>Create Match</a></li>
<li (click)="logout()"><a>Log out</a></li>
}
</code>
@if(!(isLoggedIn$ | async) ){
<li routerLink="/signup" routerLinkActive="['active']">
<a>Sign Up</a>
</li>
<li routerLink="/login"><a>Login</a></li>
} @else {
<li routerLink="/create-match"><a>Create Match</a></li>
<li (click)="logout()"><a>Log out</a></li>
}
I believe the issue may be to do with the observable omits a false initially without checking the localstorage. How can i achieve this?