Issue
I have created an angular 13 app which works great (fairly new to Angular btw). I am now having to add authentication as a pre-requisite to being able to continue to use the site. So the routing should be:
- Initial load to login page (no nav bar)
- Once logged in we load the App and Nav Bar accordingly.
- If the token has expired further routing should force to login page
- On clicking log out we route back to login.
Parts 1 and 4 are working with AuthGuards etc but I am having issues routing from the login page onto the home page and showing the Navbar correctly.
Current code: app.component.html
<div>
<app-navbar *ngIf="isLoggedIn" [isLoggedIn]="this.isLoggedIn"></app-navbar>
<router-outlet></router-outlet>
</div>
app.component.ts
ngOnInit(): void {
if (this.cacheService.load("auth-token")) {
this.isLoggedIn = true;
}
}
app-routing-module.ts
import { NgModule } from '@angular/core';
....
const routes: Routes = [{ path: 'login', component: LoginComponent },
{ path: '', component: HomeComponent, canActivate: [AuthGuardService] },
{ path: 'authed', component: AuthedComponent, canActivate: [AuthGuardService] },
{ path: '**', redirectTo: '', pathMatch: 'full' }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Login.component.ts
ngOnInit(): void {
if (this.cacheService.load("auth-token")) {
this.isLoggedIn = true;
}
}
onSubmit(): void {
const { username, password } = this.form;
const userReq: IUserRequest = {
Email: username,
Password: password,
};
this.userService.login(userReq).subscribe({
next: res => {
console.log(res);
this.isLoggedIn = res.Success == true;
this.isLoginFailed = false;
this.route.navigate(['']);
},
error: err => {
this.errorMessage = err;
this.isLoginFailed = true;
}
});
}
auth-interceptor.ts
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
if (this.cacheService.load('auth-token')) {
return true;
}
this.route.navigate(['login']);
return false;
}
So what is happening? After authenticating successfully, the app loads fine but the Navbar does not display (until I manually refresh the page). Adding in a window.location.reload in an oninit just continually refreshes the screen.
I have tried numerous ways to try and fix this, with no joy. Anyone have any ideas what could be wrong?
Thank you in advance.
Solution
The reason the navbar doesn't show up is because you never set isLoggedIn = true
in the main component after authenticating.
I would recommend putting this variable in your userService
. Services are instantiated on the first injection, so you can check the cache when initializing fields. This will check the cache on page load / refresh. You can also pipe your login observable to set this value according to the result.
export class UserService {
isLoggedIn = !!this.cacheService.load("auth-token");
constructor(private cacheService: CacheService) { }
login( ... ) {
// Your login logic
return originalObservable.pipe(tap((res) => this.isLoggedIn = res.Success === true));
}
}
You should also be caching the auth token in that pipe if you aren't already doing so.
Then just inject this service anywhere you want to check the state. Make sure you directly check the value, not just copy it onto another variable.
app.component
export class AppComponent {
constructor(private userService: UserService) {};
get isLoggedIn() {
return this.userService.isLoggedIn;
}
}
<div>
<app-navbar *ngIf="isLoggedIn"></app-navbar>
<router-outlet></router-outlet>
</div>
Answered By - Chris Hamilton
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.