I am trying to set up a check to make sure a user is authenticated in my header component to give access to routes that are only available for logged in users. That part works, however when I try to use one of those routes after I am logged in, it will change my user behavior subject back to null rendering my isAuthenticated false as well. I am not sure what is going on here, as I am not receiving errors either.
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { BehaviorSubject, Subject } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import { User } from '../models/user.model';
interface LoginData {
first_name?: string;
last_name?: string;
email?: string;
password?: string;
}
@Injectable({
providedIn: 'root',
})
export class AuthService {
apiUrl = 'http://localhost:3000/api/v1/users/';
tokenExp: Date = new Date();
user = new BehaviorSubject<User | null>(null);
constructor(private http: HttpClient, private router: Router) {}
login(form: LoginData) {
return this.http.post(this.apiUrl + 'login', form).pipe(
map((res: any) => {
const user = res;
console.log(user);
if (user.success) {
localStorage.setItem('Bearer', user.payload.token.value);
const newUser = new User(
user.payload.user.email,
user.payload.user.first_name,
user.payload.user.last_name,
user.payload.user.blogs,
user.payload.user.id,
user.payload.token
);
this.user.next(newUser);
}
})
);
}
.
.
.
}
Above is my authentication service where I set the user to my behavior subject.
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { AuthService } from 'src/app/auth/services/auth.service';
@Component({
selector: 'app-navigation',
templateUrl: './navigation.component.html',
styleUrls: ['./navigation.component.scss'],
})
export class NavigationComponent implements OnInit, OnDestroy {
isAuthenticated: boolean = false;
private userSub: Subscription;
constructor(private authService: AuthService) {
this.userSub = this.authService.user.subscribe((user) => {
this.isAuthenticated = !!user;
});
}
ngOnInit(): void {}
onLogout() {
this.authService.logout();
}
ngOnDestroy(): void {
this.userSub.unsubscribe();
}
}
This is my navigation component where I subscribe to that behavior subject and set isAuthenticated to false if my BS is null and true if there is value.
The problem lies when I try to click on any route after I log in. Once I click a route it will set is authenticated to false and my user to null. For some reason it is changing the value of my behavior subject and I don't know why.
Here is the navigation template:
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="#">Sicktastic Blogs</a>
<button
class="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarNav"
aria-controls="navbarNav"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li
class="nav-item"
routerLink="/home"
routerLinkActive="active"
*ngIf="isAuthenticated"
>
<a class="nav-link" aria-current="page" href="#">HOME</a>
</li>
<li
class="nav-item"
routerLink="/profile"
routerLinkActive="active"
*ngIf="isAuthenticated"
>
<a class="nav-link" aria-current="page" href="#">PROFILE</a>
</li>
<li
class="nav-item"
routerLink="/register"
routerLinkActive="active"
*ngIf="!isAuthenticated"
>
<a class="nav-link">REGISTER</a>
</li>
<li
class="nav-item"
routerLink="/login"
routerLinkActive="active"
*ngIf="!isAuthenticated"
>
<a class="nav-link">LOGIN</a>
</li>
<li class="nav-item" *ngIf="isAuthenticated">
<a class="nav-link" (click)="onLogout()">LOGOUT</a>
</li>
</ul>
</div>
</div>
</nav>