Reputation: 119
The problem seems to be strange.The angular 5 application is using firebase authentication and ngrx.The default route is a component called HomeLayout and declared in app module.I have another modules called Userlist and Settings. They are lazy loaded in the app.routing. The problem is when i click on login the firebase returns the auth information and i update the logged in status to AppStore.And there is an AuthService, this is subscribed to store.The application works fine and no issues with change detection without using AuthenticatedGuard.When i use AuthenticatedGuard the initial route ngModel, ngClass items won't work as expected.If i navigate to other route using routerlink.Then if i returns to the initial redirect page(In our case Userlist) things will work as normal.
app.routing.ts
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { NotFoundComponent } from './components/not-found/not-found.component';
import { HomeLayoutComponent } from './containers/home-layout/home-layout.component';
import { LoginComponent } from './components/login/login.component';
import { SignupComponent } from './components/signup/signup.component';
import { AuthenticatedGuard } from './core/guards/authenticated.guard';
import { UnauthenticatedGuard } from './core/guards/unauthenticated.guard';
const appRoutes: Routes = [
{ path: '', redirectTo: 'userlist', pathMatch: 'full'},
{ path: '', component: HomeLayoutComponent, canActivate: [AuthenticatedGuard],
children: [
{
path: 'userlist',
loadChildren: 'app/containers/userlist/userlist.module#UserlistModule'
},
{
path: 'settings',
loadChildren: 'app/containers/settings/settings.module#SettingsModule'
}
]
},
{ path: 'login', component: LoginComponent, canActivate: [UnauthenticatedGuard]},
{ path: 'signup', component: SignupComponent },
{ path: 'unavaliable', component: NotFoundComponent },
// otherwise redirect to home
{ path: '**', redirectTo: 'unavaliable' }
];
export const appRouting: ModuleWithProviders = RouterModule.forRoot(appRoutes, { enableTracing: true });
auth.effect.ts
@Effect()
googleloginAction$: Observable<Action> = this.actions$
.ofType(authActions.AuthActionTypes.GOOGLE_LOGIN_REQUESTED)
.map(action => action)
.switchMap((payload: any) => this.authService.googleLogin()
.map(res => (new authActions.GoogleLoginSuccessAction(new authActions.AuthUserPayload(res))))
.do(() => this.router.navigate(['/userlist']))
.catch((error) => Observable.of(new authActions.AuthErrorAction({error: error})))
);
AuthGuard Service
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Store } from '@ngrx/store';
import { AppState, isLoggedIn } from '../../reducers';
@Injectable()
export class AuthGuard {
constructor(private store: Store<AppState>) {}
isLoggedIn(): Observable<boolean> {
return this.store.select(isLoggedIn).do(x => console.log('User Logged:', x) );
}
}
AuthenticatedGuard
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRoute, Routes } from '@angular/router';
import { AuthGuard } from './auth.guard';
import { Observable } from 'rxjs/Observable';
import { Router } from '@angular/router';
import 'rxjs/add/operator/do';
@Injectable()
export class AuthenticatedGuard implements CanActivate {
constructor(private authGuard: AuthGuard,
private router: Router,
private activatedRoute: ActivatedRoute) {
}
canActivate(): Observable < boolean > {
return this.authGuard.isLoggedIn().map(loggedIn => {
if (!loggedIn) {
this.router.navigate(['/login'], {
relativeTo: this.activatedRoute
});
return false;
}
return true;
});
}
}
Similarly i have one more guard that is applied on the Login.So that it will redirect to userlist route if logged in. My doubt is that any issues with the router.navigate method or the auth guards, because the router link navigation works as expected.
Upvotes: 0
Views: 718
Reputation: 119
The issue was due to a bug in angular router lib.Fixed by using ngZone.
this.ngZone.run(() => this.router.navigateByUrl('/waitlist'))
Upvotes: 2