angularlocal-storageangular-routing

Navigation to home page from login page is not working the second time


By default, Login page page opens if user is logged out. onLogin method works fine the first time and navigates to home page. On logout, it navigates back to login page. If I try again to login again without refreshing the page, navigation to home page does not work. Below is my sample code.

app.route.ts

  export const routes: Routes = [
  {
    path: '',
    redirectTo: 'home',
    pathMatch: 'full',
  },
  {
    path: 'login',
    component: LoginComponent,
  },
  {
    path: 'home',
    component: HomeComponent,
    canActivate: [authGuard],
  }];

authGuard

    export const authGuard: CanActivateFn = (route, state) => {
        const router = inject(Router);
        const isLoggedIn = !!localStorage.getItem('loggedIn');
        if (isLoggedIn) return true;
        else {
            router.navigate(['/login']);
            return false;
        }
    };

login.component.ts

onLogin() {
    const { user, password } = this.loginForm.value;
    if (user.trim() === 'admin' && password.trim() === 'admin') {
      localStorage.setItem('loggedIn', 'true');
      this.router.navigate(['/home']);
    } else {
      alert(`Incorrect Username or password. Please try again.`);
    }
  }

home.component.ts

onLogout() {
  localStorage.removeItem('loggedIn');
  this.router.navigate(['/login']);
}

Solution

  • Here are two key points of this issue, and I hope it will resolve the problem.
    1. HomeComponent

    The Router is already available application-wide. I'll remove it.

    @Component({
      selector: 'app-home',
      standalone: true,
      imports: [],
      templateUrl: './home.component.html',
      styleUrl: './home.component.css',
      providers: [Title], // Remove "Router"
    })
    export class HomeComponent implements OnInit {
      title = inject(Title);
      router = inject(Router);
      authService = inject(AuthService);
    }
    

    2. LoginComponent
    The AuthService is provided in the root, which means it's a singleton.
    However, in login.component.ts, you have providers: [Title, AuthService].

    This creates a new instance of AuthService every time when the LoginComponent is created.

    @Component({
      selector: 'app-login',
      standalone: true,
      imports: [ReactiveFormsModule],
      templateUrl: './login.component.html',
      styleUrl: './login.component.css',
      providers: [Title], // Remove "AuthService"
    })
    export class LoginComponent implements OnInit {
      title = inject(Title);
      router = inject(Router);
      authService = inject(AuthService);
    }
    

    By the way, You already inject "Title" in the code below. So, you can also remove "Title" in the providers.