1

I have an Angular app.

  • On the app init we should show redirecting spinner (user is not logged in)
  • When the user is logged in, then we should show content

I've done it as below: HTML:

<div *ngIf="(isLoggedIn$ | async); else loading">
    <!-- some other content -->
    <router-outlet></router-outlet>
</div>

<ng-template #loading>
    <app-spinner text="Redirecting..."></app-spinner>
</ng-template>

TS:

isLoggedIn$: Observable<boolean>;

constructor(private authService: AuthService) {}

ngOnInit() {
    this.isLoggedIn$ = this.authService.isLoggedIn();
}

It works well on the app init. When the user is logged in, I still see the redirection spinner. I have to refresh the window to see the router-outlet content.

My temporary workaround is to put <router-outlet> inside <ng-template #loading>, eg:

<ng-template #loading>
    <app-spinner text="Redirecting..."></app-spinner>
    <router-outlet></router-outlet> <!-- HERE workaround -->
</ng-template>

But don't want to use this workaround permanently as I want to fix this Observable problem - as I mentioned it is not refreshed even when the console.log() says that I'm logged in.

Here is my Auth Service:

@Injectable({
    providedIn: 'root'
})
export class AuthService {

  manager: UserManager = new UserManager(environment.settings);

  constructor() {
  }

  getUser(): Observable<User> {
    return from(this.manager.getUser());
  }

  isLoggedIn(): Observable<boolean> {
    return this.getUser()
      .pipe(
        map(user => {
          return user != null && !user.expired;
        })
      );
  }

  startAuthentication(): Promise<void> {
    return this.manager.signinRedirect();
  }

  completeAuthentication(): Observable<User> {
    return from(this.manager.signinRedirectCallback());
  }

  async signOut() {
    await this.manager.signoutRedirect();
  }
}

Of course, I am using CanActivate as well.

7
  • 2
    Can we see the code of this.authService.isLoggedIn? Commented May 28, 2019 at 15:15
  • How is this a workaround? Doesn't the app-spinner still spin? Commented May 28, 2019 at 15:31
  • 2
    Don't conditionally remove the <router-outlet> because the router can not active a route. This has nothing to do with the isLoggedIn$ observable. Commented May 28, 2019 at 15:31
  • 1
    If you want to control routing, then use one of the router features. CanActivate for example. Commented May 28, 2019 at 15:31
  • 1
    Just to be sure - does the observable emit? Maybe tap it with console.log to check. Commented May 28, 2019 at 15:43

1 Answer 1

1

My solution is to add emitCompleted method to AuthService and calling it from AuthCallback component.

AuthService:

private isLoggedInState = new BehaviorSubject<boolean>(false);

isLoggedIn(): Observable<boolean> {
    return this.isLoggedInState.asObservable();
}

emitCompleted(user: User) {
    this.isLoggedInState.next(user != null && !user.expired);
}

AuthCallback component:

export class AuthCallbackComponent implements OnInit {

  constructor(
    private authService: AuthService,
    private router: Router
    ) { }

  ngOnInit() {
    this.authService.completeAuthentication()
      .subscribe((result => {
        this.authService.emitCompleted(result);
      })
    );
  }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.