title: How to make canActivate to wait for store loading
body: <p>I'm trying to implement a guard in my project, that should wait until ngrx-store's loading complete and after this check is user authenticated or not. The problem, that guard doesn't wait completion of store's loading. </p>
  
  <p><strong>My app-routing.module.ts:</strong></p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>import { NgModule } from '@angular/core';
  import { RouterModule, Routes } from '@angular/router';
  import {
    IsAuthGuard,
    HomeRedirectGuard
  } from '@app/core';
  import { LoginComponent } from './static';
  
  const routes: Routes = [
    {
      path: '',
      redirectTo: 'home',
      pathMatch: 'full',
    },
    {
      path: 'settings',
      loadChildren: 'app/features/settings/settings.module#SettingsModule',
      canActivate: [IsAuthGuard, HomeRedirectGuard]
    },
    {
      path: 'login',
      component: LoginComponent,
      data: { title: 'tts.menu.login' }
    },
   
    {
      path: 'home',
      loadChildren: 'app/features/home/home.module#HomeModule',
      data: { title: 'tts.menu.home' },
      canActivate: [IsAuthGuard, HomeRedirectGuard]
    }
    {
      path: '**',
      redirectTo: 'home'
    }
  ];
  
  @NgModule({
    // useHash supports github.io demo page, remove in your app
    imports: [
      RouterModule.forRoot(routes, {
        useHash: true,
        scrollPositionRestoration: 'enabled'
      })
    ],
    exports: [RouterModule]
  })
  export class AppRoutingModule { }</code></pre>
  </div>
  </div>
  </p>
  
  <p>The idea of IsAuthGuard is just check if we have authentication or not, and dispatch login request action if not authenticated. </p>
  
  <p><strong>IsAuthGuard:</strong></p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>import { Injectable } from '@angular/core';
  import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlSegment, CanLoad, Route } from '@angular/router';
  import { Observable, of } from 'rxjs';
  import { Store, select } from '@ngrx/store';
  import { selectAuthisAuthenticated } from '@app/root-store/auth-store/selectors';
  import { AuthStoreActions } from '@app/root-store';
  import { take, switchMap } from 'rxjs/operators';
  
  @Injectable()
  export class IsAuthGuard implements CanActivate, CanLoad {
  
    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable&lt;boolean&gt; {
      return this.canLoad(route.routeConfig, null);
    }
  
    constructor(private store: Store&lt;any&gt;, private router: Router) { }
  
    canLoad(route: Route, segments: UrlSegment[]): Observable&lt;boolean&gt; | boolean {
      console.log("CanLoad isAuth");
  
      return this.store
        .pipe(select(selectAuthisAuthenticated),
          take(1),
          switchMap(isAuth =&gt; {
            if (!isAuth) {
              this.store.dispatch(new AuthStoreActions.AutoLoginRequestAction());
            }
            return of(true);
          }));
    }
  }</code></pre>
  </div>
  </div>
  </p>
  
  <p>And finally my <strong>HomeRedirectGuard</strong> service, that doesn't work:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>import { Injectable } from '@angular/core';
  import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
  import { Observable, Subject } from 'rxjs';
  import { Store, select } from '@ngrx/store';
  import { selectAuthUser, selectAuthIsLoading} from '@app/root-store/auth-store/selectors';
  import { Constants } from '../constants/constants.enum';
  import { takeUntil, last, map } from 'rxjs/operators';
  
  @Injectable()
  export class HomeRedirectGuard implements CanActivate{
    isUser = false;
    private unsubscribe$: Subject&lt;void&gt; = new Subject&lt;void&gt;();
  
    constructor(private store: Store&lt;any&gt;, private router: Router) {
      this.store
        .pipe(select(selectAuthUser),
          takeUntil(this.unsubscribe$))
        .subscribe(user =&gt; {
          this.isUser = !!user;
          console.log("USER =", user);
        });
    }
  
    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable&lt;boolean&gt; {    
      return this.checkAuth();
    }
  
  
    checkAuth(): Observable&lt;boolean&gt; | boolean {
      console.log("CanLoad Home");
  
       return  this.store.pipe(select(selectAuthIsLoading),
        last(val =&gt; val === false),
        map(isLoading =&gt; {
          console.log("isLoading = ", isLoading);
          console.log("isUser = ", this.isUser);
          let redirectUrl;
  
          if (this.isUser) {
            redirectUrl = Constants.HOME_URL;
          } else {
            redirectUrl = Constants.LOGIN_URL;
          }
          this.router.navigate([redirectUrl]);
          console.log("HOME redirectUrl=", redirectUrl);
          return true;
        })
      );
    }
  }</code></pre>
  </div>
  </div>
  </p>
  
  <p>And I see in console this:
  <a href="https://i.stack.imgur.com/VrkrI.jpg" rel="nofollow noreferrer">enter image description here</a></p>
  
  <p>CanLoad isAuth</p>
  
  <p>[DEBUG] action: [Auth] Auto login request {payload: undefined, oldState: {…}, newState: 
   auth: {isAuthenticated: false, user: null, redirectUrl: null, error: null, <strong>isLoading: true</strong>} ...</p>
  
  <p>USER = null</p>
  
  <p>CanLoad Home</p>
  
  <p>[DEBUG] action: [Auth] Auto login failure {payload: undefined, oldState: {…}, newState:
  auth: {isAuthenticated: false, user: null, redirectUrl: null, error: null, <strong>isLoading: false</strong>}</p>
  
  <p>So, I come to HomeRedirectGuard, but Guard doesn't wait last emission of select, where isLoading is false and there are information in store, are there authentication or not.</p>