Search code examples
angularrxjsobservableangular-routerangular-router-guards

What's the difference between Observable<UrlTree> and UrlTree?


I'm implementing a canActivate guard for one of my app components.

Based on the documentation, both UrlTree and Observable<UrlTree> are valid return types.

I understand that by wrapping 'a thing' into an observable would make the thing asynchronous, but I don't understand the difference in the router/routing context.

What are the differences between UrlTree and Observable<UrlTree> in terms of how router handles them?

When do you use one over the other?

I assume the same reasonings could also apply to <boolean> and Observable<boolean>

UrlTree version:

export class myGuard implements CanActivate {
  constructor(private router: Router) {}
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return this.router.parseUrl('newRoute');
  }
}

Observable version:

import { of } from 'rxjs';
export class myGuard implements CanActivate {
  constructor(private router: Router) {}
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return of(this.router.parseUrl('newRoute'));
  }
}

I've tried both versions, and both work fine in dev environment.


Solution

  • The difference is just how the guard treats the response type... if it’s an observable, it subscribes and uses the value of the subscription to make a routing decision. If it’s not an observable, it just uses the value returned to make the decision. It’s for facilitate but not force an async function for your guard.

    Use an observable when your decision is made based on something async... like a subject value or an http request or something. Use a non observable when your decision made based upon something synchronous, like a localStorage value or something.