title: Angular authentication wait to set permissions in local storage before guard
body: <p>I try to implement an authentication service in my project.
  A backend provide me a sso token and the current user permissions.</p>
  
  <pre><code>{
      "success":true,
      "data: [
              {
               "first_name":"Michel",
               "last_name":"Drucker",
               "email":"mdrucker@fr3.com",
               "company":"fr3",
               "image":"http://micheldrucker.com/moi.jpg",
               "permissions":["ADMIN"]
              }
             ]
  }
  </code></pre>
  
  <p>I want to set in local storage those data, but my guard doesn't wait for those data to be set. 
  So my verification in guard doesn't work, I have an error 
  <code>Cannot read property 'data' of null</code>.</p>
  
  <p>To prevent this error, I set an item permissions, before treatment like <code>localStorage.setItem('permissions', 'xxx');</code></p>
  
  <p><strong>app.component.ts</strong></p>
  
  <p>saves the token that comes from the url with an event snapshot</p>
  
  <pre class="lang-js prettyprint-override"><code>this.router.events.subscribe((event: Event) =&gt; {
              // put sso and permissions in local storage
              if (event instanceof ChildActivationStart) {
                  if (event.snapshot.queryParams.sso !== undefined) {
                      localStorage.setItem('sso', event.snapshot.queryParams.sso);
                      this.apiService.permissions().subscribe((data) =&gt; {
                          localStorage.setItem('permissions', data.data[0].permissions);
                      });
                  }
              }
          });
  </code></pre>
  
  <p><strong>authorization.guard.ts</strong> </p>
  
  <p>check route permissions rules, block user if is not authorized</p>
  
  <pre class="lang-js prettyprint-override"><code>canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable&lt;boolean&gt; | Promise&lt;boolean&gt; | boolean {
          // declaration of route roles path
          const allowedRoles = next.data.permissions.only;
          // check if user is authorized
          const isAuthorized = this.authorizationService.isAuthorized(allowedRoles);
  
          if (!isAuthorized) {
              this.snackbarMessage.openErrorSnackBar(this.translate.instant('GUARD.UNAUTHORIZED'));
              this.router.navigate(['/']);
          }
  
          return isAuthorized;
      }
  </code></pre>
  
  <p><strong>authorization.service.ts</strong> </p>
  
  <p>control the user</p>
  
  <pre class="lang-js prettyprint-override"><code>isAuthorized(allowedRoles: string[]): boolean {
          // check if the list of allowed roles is empty, if empty, user can access
          if (allowedRoles == null || allowedRoles.length === 0) {
              return true;
          }
          // get permissions stored at app init after login
          const permissions = localStorage.getItem('permissions');
  
          // if it's not exists, delete sso token and go back to login
          if (!permissions) {
             localStorage.removeItem('sso');
             this.router.navigate(['/login']);
          }
  
          // check if user has route allowed roles
          const rolesIsFound = allowedRoles.filter(element =&gt; permissions.includes(element));
  
          let userAuthorized = false;
  
          if (rolesIsFound.length &gt; 0) {
              userAuthorized = true;
          }
  
          return userAuthorized;
      }
  </code></pre>
  
  <p><strong>route.ts</strong></p>
  
  <pre><code>{
          path: '',
          component: FuseHomeComponent,
          canActivate: [AuthorizationGuard],
          data: {
              permissions: {
                  only: ['ADMIN'],
              }
          }
      },
  </code></pre>
  
  <p><strong>auth-interceptor.ts</strong></p>
  
  <pre><code>    intercept(request: HttpRequest&lt;any&gt;, next: HttpHandler): Observable&lt;HttpEvent&lt;any&gt;&gt; {
          const sso = localStorage.getItem('sso');
          if (sso) {
              request = request.clone({
                  setHeaders: {
                      'Content-Type': 'application/json',
                      'X-API-KEY': sso,
                  }
              });
          }
  
          return next.handle(request).pipe( tap(() =&gt; {},
              (err: any) =&gt; {
                  if (err instanceof HttpErrorResponse) {
                      if (err.status !== 401) {
                          return;
                      }
                      localStorage.removeItem('sso');
                      localStorage.removeItem('permissions');
                      this.snackbarMessage.openErrorSnackBar(this.translate.instant('GUARD.UNAUTHORIZED'));
                      this.router.navigate(['/login']);
                  }
              }));
      }
  </code></pre>
  
  <p>I don't think my code is very good, store the data in the app component don't seems to be good. By setting the permissions 'xxx' users can access see the app a few seconds until the http response forbid the user. I think this is just a "waiting" problem.</p>