I'm trying to create an "auth app" with redux(ngrx) and I'm trying to use my app state in the secret guard. Here you can see my github: https://github.com/tamasfoldi/ngrx-auth/tree/router This is how my guard looks like:
@Injectable()
export class SecretGuard implements CanActivate {
constructor(private store: Store<AppState>, private router: Router) {
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return this.store.let(getLoginState())
.map(state$ => state$.isLoggedIn)
}
}
It returns with the isLoggedIn attribute which should be OK because router resolves promises and observable, but the router block it when I navigate to the secret part. Here are my routes:
export const appRoutes: Routes = [
{
path: '',
redirectTo: 'auth',
pathMatch: 'full'
},
{
path: 'auth',
children: [
{ path: '', redirectTo: 'login', pathMatch: 'full' },
{ path: 'login', component: LoginComponent },
{ path: 'register', component: RegisterComponent }
]
},
{
path: 'secret',
canActivate: [SecretGuard],
children: [
{ path: '', redirectTo: 'default', pathMatch: 'full' },
{ path: 'default', component: DefaultSecretComponent }
]
}
];
In redux I receive the init state so I also have tried to skip the first emission in my observable, but it neither works. Here is the skipping code:
@Injectable()
export class SecretGuard implements CanActivate {
constructor(private store: Store<AppState>, private router: Router) {
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return this.store.let(getLoginState())
.skip(1)
.map(state$ => state$.isLoggedIn)
}
}
If I use my AuthService's auth function it is working properly, but that solution is not "redux-like". Can you help me with it how to make it work with ngrx? Or I'm not able to use my appstate in guards?
You can synchronously get value from store, don't need to "stream everything" (:
https://github.com/ngrx/store#getstate-getvalue-and-value
import 'rxjs/add/operator/take';
function getState(store: Store<State>): State {
let state: State;
store.take(1).subscribe(s => state = s);
return state;
}
@Injectable()
export class SecretGuard implements CanActivate {
constructor(private store: Store<AppState>, private router: Router) { }
canActivate():boolean {
return getState(this.store).login.isLoggedIn;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With