4
votes

In my application I have an homepage after the user logged in and some other pages. The problem is that when I am inside in one of these other pages and I refresh the page it sends me to home again. This is my Routes:

const routes: Routes = [
  {
    path: '', redirectTo: '/home', pathMatch: 'full'
  },
  {
    path: 'login',  component: LoginComponent 
  },{
    path: 'list',  component: ListComponent, canActivate : [AuthGuardService]
  },{
    path: 'home', component: HomeComponent, canActivate : [AuthGuardService]
  },{
    path: 'detail/:id',  component: HomeComponent, canActivate : [AuthGuardService],
  },{
    path: '**', redirectTo: 'login' ,pathMatch: 'full'
  }
];

the app-component has the router outlet

<div [ngClass]="{'container': (isLoggedIn$ | async), 'mt-2': (isLoggedIn$ | async)}" class="h-100">
    <router-outlet></router-outlet>
</div>

So, what I expect? First of all, if I am i "list" page (localhost:4200/list) and I refresh this page, it should be stay there. In that page. But now it redirects me to localhost:4200/home. Of course, when I click a list item it should send me to localhost:4200/detail/itemId but it sends me always to home. Thanks

Edit with AuthGuardService:

export class AuthGuardService implements CanActivate {
  constructor(private route : Router, private store: Store<AppState>) {}

  canActivate() {
    return this.store
      .pipe(
          select(isLoggedIn),
          tap(loggedIn => {
              if (!loggedIn) {
                this.route.navigate(['login']);
              }
          })
      )  
  }
}

I add the login effect

login$ = createEffect(() =>
        this.actions$
            .pipe(
                ofType(userActions.login),
                tap(action => {
                    localStorage.setItem('userInfo',
                    JSON.stringify(action.user))
                    this.router.navigate(['home']);
                })
            )
    ,{dispatch: false});

SOLUTION:

Well, after some hours of debugging I found the solution. basically I removed this.router.navigate(['home']); in the AuthGuardService and I put it on login function of the component as soon as the user is logged in. Put the this.router.navigate(['home']); in the AuthGuardService fires the guard everytime I refresh the page and so everytime it redirect me at home. That's it. Thanks

1
can you add authGuardService code - programoholic
@programoholic sure, done - Atlas91
I think you should replace ' ' path in the bottom - programoholic
Do you mean in the Routes? - Atlas91
I created a STACKBLITZ (stackblitz.com/edit/…) with mock guard and it works properly. (you can change login state under login tab -> clikk on checkbox, guarded route in my example is LIST). Thus, it means that your guard probably returns FALSE. You are welcome to fork and change my STACKBLITZ, to reproduce your issue, ant then I will try to help - Andriy

1 Answers

0
votes

The order of routes is important because the Router uses a first-match wins strategy when matching routes, so more specific routes should be placed above less specific routes.

  • List routes with a static path first
  • Followed by an empty path route, which matches the default route.
  • The wildcard route comes last because it matches every URL.

The Router selects it only if no other routes match first.

Reference: https://angular.io/guide/router#route-order

So you change the order as follows

const routes: Routes = [
  {
    path: 'login',  component: LoginComponent 
  },{
    path: 'list',  component: ListComponent, canActivate : [AuthGuardService]
  },{
    path: 'home', component: HomeComponent, canActivate : [AuthGuardService]
  },{
    path: 'detail/:id',  component: HomeComponent, canActivate :  [AuthGuardService],
  }
  {
    path: '', redirectTo: '/home', pathMatch: 'full'
  },
  ,{
    path: '**', redirectTo: 'login' ,pathMatch: 'full'
  }
];