0

I am using AuthGuard to protect components until a user is logged in. The AuthGuards works, but whenever changes in the components are made and saved, the page refreshes itself and becomes blank and there are no errors in the console.

I have looked at similar issues found on Stack Overflow, but the problems are different and have not found the solution, yet.

app-routing.module.ts:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { LoginComponent } from './login/login.component';
import { NavigationComponent } from './navigation/navigation.component';
import { HomeComponent } from './home/home.component';
import { AuthguardService } from './authguard.service';
import { MembersComponent } from './members/members.component';
import { SubscriptionsComponent } from './subscriptions/subscriptions.component';
import { TicketsComponent } from './tickets/tickets.component';


export const routes: Routes = [
    { path: '', component: LoginComponent },
    {
        path: 'app-home', component: HomeComponent,
        canActivate: [AuthguardService],
        children: [
            { path: 'login', component: LoginComponent },
            { path: 'navigation', component: NavigationComponent },
            { path: 'member', component: MembersComponent },
            { path: 'subscription', component: SubscriptionsComponent },
            { path: 'ticket', component: TicketsComponent },
        ]
    },
    { path: '**', redirectTo: '' }
];

@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule]
})
export class AppRoutingModule { }
export const routingComponents = [LoginComponent]

authguard.service.ts:

import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { LoginService } from './login.service';
@Injectable({
  providedIn: 'root'
})
export class AuthguardService implements CanActivate {
  constructor(private loginService: LoginService, private router: Router) { }
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):
    boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree> {
    const token = this.loginService.getToken();
    if (!token) {
      this.router.navigate(['/']);
      return false;
    }
    return true;
  }
}

I expect the new changes to be visible right away, whenever new changes are made, instead of having to go all the way back to the login page, login again and then go back to the component to see the new changes.

  • Add `debugger;` before the `if (!token)` and validate if it breaks in the AuthGuard, the value of `token` etc... nothing better then debugging! – j3ff Mar 23 '20 at 10:59
  • Another thing maybe that can help is to enable router tracing which shows Angular router activity in the console: `RouterModule.forRoot(routes, { enableTracing: true })`. – j3ff Mar 23 '20 at 12:14
  • I tried your suggestion and the results are: https://paste.pics/83db2975532185bc19b9d037e560d8ec https://paste.pics/9b31e9d3c7cc9d61729a2596185d5268 –  Mar 23 '20 at 12:32
  • I think I found your problem, see my answer – j3ff Mar 23 '20 at 12:32

3 Answers3

0

pathMatch: 'full'

You need to add pathMatch: 'full' to the path: '' route otherwise Angular Router will match it on application load without interpreting all the URL.

{ path: '', component: LoginComponent, pathMatch: 'full' },

Basically, pathMatch: 'full' means that the whole URL path needs to match and is consumed by the route matching algorithm.

Duplicated Route

Also, you have a duplicated route pointing toward LoginComponent... I would remove the app-home/login route that is behind the AuthGuard since it would required you to be logged-in to be able to access it:

{ path: '', component: LoginComponent, pathMatch: 'full' },
{
    path: 'app-home', component: HomeComponent,
    canActivate: [AuthguardService],
    children: [
        { path: 'login', component: LoginComponent }, // <= remove this route
        { path: 'navigation', component: NavigationComponent },
        { path: 'member', component: MembersComponent },
        { path: 'subscription', component: SubscriptionsComponent },
        { path: 'ticket', component: TicketsComponent },
    ]
}
j3ff
  • 5,719
  • 8
  • 38
  • 51
  • Still doesn't work.. Still blank page after every compile.. I have tried to remove the authguard from canActivate: [] and it's not working. I think the problem lies somewhere else.. –  Mar 23 '20 at 13:11
  • Damn sorry to hear... is your url ending up on `app-home/member` after reloading? – j3ff Mar 23 '20 at 13:15
  • Nope.. it stays at the same url. I have also confirmed that it doesn't matter on which component I make the changes, after compiling, the url where I'm on it will refresh itself and the page becomes blank. Here is a screenshot: https://paste.pics/9fdcff322b8f6273a0e5d0edefff6c35 –  Mar 23 '20 at 13:36
  • Your last screenshot shows `404` for Angular compiled source... that might be the problem! – j3ff Mar 23 '20 at 13:48
0

you can use it like this

export const appRoutes : Routes=[
{ path : '' , component : HomeComponent},
{ path : '',
    runGuardsAndResolvers:'always',
    canActivate:[AuthGuard],
    children:[
        { path: 'members', component: MembersComponent },
        { path: 'member/edit', component: MemberEditComponent }
    ]
},

{ path : '**' , redirectTo : '' , pathMatch : 'full'}

];

0

Thanks for all the help everyone and sorry for the wait! But I have finally found the answer to my problem. It seems to be a typo which I made at the very beginning..

index.html:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Angular</title>
  <base href="./"

base href="./" changed to base href="/"

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body class="body-app">
  <app-root></app-root>
</body>
</html>