0

Good day!

I have an Angular 7 application for working with time cards. I am using a CanActivate Guard on being able to enter a component. The CanActivate code uses an Observable to determine if they should be let through or redirected.

  timecardID: number;
  constructor(private globals: Globals, private router: Router, private securityService: SecurityService) { }
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | boolean {

    if (next.params.timecardId) {
      this.timecardID = +next.params.timecardId;
      return this.hasAccessToTimecard();
    }

    return this.empNumber === this.globals.empNumber;
  }


  //Does current user have access to this specific timecard
  hasAccessToTimecard(): Observable<boolean | UrlTree> {
    return this.securityService.hasRightsToTimecard(this.timecardID);
  }

The service it calls looks like:

  private readonly HasRightsToTimecardURI = 'api/Security/HasRightsToTimecard';
  private readonly HasRightsToEmployeeURI = 'api/Security/HasRightsToEmployee';

  constructor(private http: HttpClient, @Inject('BASE_URL') private baseUrl: string, private router: Router) { }

  //I don't like the use of router to navigate here.  But without it, on false return the UrlTree isn't used for redirections.
  public hasRightsToTimecard(timecardID: number): Observable<boolean | UrlTree> {
    let parameters = new HttpParams();
    parameters = parameters.set('timecardID', String(timecardID));

    return this.http.get<boolean | UrlTree>(this.baseUrl + this.HasRightsToTimecardURI, { params: parameters }).pipe(
      tap((result) => {
        this.router.navigate(['/home']);
        return  result ? result : this.router.createUrlTree(['/home']);
      })
    );
  }

I have verified that the logic works that when the API returns false, that a UrlTree is created and returned, as well as a API result of true returns fine as well.

However, my actual outcome is that if I were trying to use the controls to access the route:

  1. Using controls in the app's component, I have correct access, guard lets me through
  2. Using controls in the app's component, I don't have correct access, guard keeps me where I am (denying me to that route). When it should reroute me.
  3. If I try to 'land' right on that route from typing it in my browser, I just get a blank router-outlet.

Can anyone help me?

Also: Possible pertinent route (removed other items):

const routes: Routes = [
  {
    path: 'timecards', canActivateChild: [RightsGuard], children: [
      { path: 'edit/:timecardId', canActivate: [TimecardGuard], component: TimecardNewComponent }
    ]
  }
];
Avogadro
  • 353
  • 2
  • 11
  • I solved my own issue after plugging at this for awhile. The use of tap() is incorrect. Per documentation (https://rxjs-dev.firebaseapp.com/api/operators/tap), tap does not modify the resulting value, it will always return the original value. Use of map() was the correct function to use. – Avogadro May 07 '20 at 14:51

1 Answers1

0

I solved my own issue after plugging at this for awhile. The use of tap() is incorrect. Per documentation (http://rxjs-dev.firebaseapp.com/api/operators/tap), tap does not modify the resulting value, it will always return the original value. Use of map() was the correct function to use.

Avogadro
  • 353
  • 2
  • 11