简体   繁体   中英

Get result from multiple Observable<boolean> - Angular 5 route guard

In Angular 5 I am using two service calls to see if the user should be allowed to see the page, this is using Route guard. However with RXJS, I'm not sure about the best way to handle this.

import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { AuthService } from './auth.service';
import { SponsorService } from '../sponsor.service';
import Rxjs = require("rxjs");
import { Observable } from 'rxjs/Observable';
import { map } from 'rxjs/operators';
import { Subscription } from 'rxjs';

@Injectable()
export class SponsorGuard implements CanActivate {

  constructor(
    private readonly auth: AuthService,
    private readonly sponsorService: SponsorService,
    private readonly router: Router) {
  }

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {

   // console.log(this.isSponsor());
    //console.log(this.isValidSponsor(route));

   // return true;

    if (this.isSponsor() && this.isValidSponsor(route)) {
      return true;
    };
    return false;
  };

//  canGoToSponsorPage() : Subscription {
//    const isSponsorObservable = this.isSponsor();
//    const isValidSponsorRecordObservable = this.isValidSponsor();
//    const arrayOfRequests = [isSponsorObservable, isValidSponsorRecordObservable];
//
//      return Observable.forkJoin(arrayOfRequests).subscribe(results => {
//
//        const result = (results[0] && results[1]);
//      });
//  }

  isSponsor(): Observable<boolean> {

    return this.auth.isSponsor().map(isSponsor => {

      if (!isSponsor) {
        console.log("getting redirected");

        this.router.navigateByUrl('home');
        return false;
      }

      console.log("access granted");
      return true;
    });
  }

  isValidSponsor(route: ActivatedRouteSnapshot) : Observable<boolean> {

    const sponsorId = Number(route.params["sponsorId"]);
    const applicationId = Number(route.params["applicationId"]);

    console.log(sponsorId);
    console.log(applicationId);

    return this.sponsorService.getSponsorDetails(sponsorId, applicationId).map(validSponsorRecord => {

      console.log(validSponsorRecord);

      if (!validSponsorRecord) {
        console.log("getting redirected");
        return false;
      }

      console.log("access granted");
      return true;
    });
  };
};

I'm using two helper methods that return Observable and I want to chain both of them together and see if the result of both of those observables are true.

At the moment I am doing this:

    if (this.isSponsor() && this.isValidSponsor(route)) {
      return true;
    };
    return false;
  };

I think this is checking to see if the object is not null rather than if the result of the service call returns true or false.

Any advice how to handle this?

The value in Observable is in the future. It is wrapped inside. You can not access it directly. To achieve it, you have to use rxjs operators to manipulate the output

For this case, you have to wait both Observables returning results with forkJoin . canActivate method can accept Observable output. So the code will be:

import { forkJoin } from 'rxjs';

...
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {

  return forkJoin(this.isSponsor(), this.isValidSponsor(route)).pipe(
    map(([a, b]) => a && b)
  );
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM