web-dev-qa-db-de.com

Warten Sie, bis http in Guard aktiviert ist Angular 5

Ich verwende einen Guard für eine Angular -Anwendung, um anfängliche kritische Daten aufzulösen. Auf der Version 4 von Angular habe ich es so gemacht:

// app.routing.ts
routing = [{
    path: '', component: AppComponent, canActivate: [ResolveGuard],
}];

// resolve.guard.ts
@Injectable()
export class ResolveGuard implements CanActivate {
    constructor(
        private _api: ApiService,
    ) { }

    canActivate(): any {
        return this._api.apiGet('my/url').map(response) => {
            if ( response.status === 'success') {
                // Consume data here
                return true;
            }

            return false;
        }).first();
    }
}

Da die neue Version von Http auf Angular 5 die Eigenschaft .map() nicht mehr verwendet, funktioniert dies nicht.

Wenn ich .map() in .subscribe() ändere, werden keine Fehler ausgegeben, die Anwendung wird jedoch nie ordnungsgemäß aufgelöst. Wenn Sie dagegen .first() und/oder .map() verwenden, treten einige Fehler auf, die in dieser Version zu erwarten sind.

Was soll ich in diesem Fall tun?

Ich muss diese Route nur aktivieren, wenn die ursprünglichen Daten geladen sind.


Bearbeiten, um Informationen zur Funktion apiGet hinzuzufügen:

constructor(private _http: HttpClient) {}

public apiGet(url: string): any {
    return this._http
        .get(this.apiUrl + url)
        .catch(this.handleError.bind(this));
}
4
celsomtrindade

Also, als Erstes: Vermeiden Sie nach Möglichkeit die Verwendung von any, besonders wenn Sie wissen, welcher Typ wohin gehört.

export interface FooInterface {
  status: string;
  fooString : string;
  fooNumber : number;
}

Zuerst definiere ich die Schnittstelle des Dienstes auf eine saubere Art und Weise und dann refaktoriere ich die Wachklasse.

AKTUALISIERTE ANTWORT für rxjs 6.x

import { throwError, Observable } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class FooService {
   constructor(private _http: HttpClient) {}

   public apiGet(url: string): Observable<FooInterface> {
    return this._http
        .get<FooInterface>(this.apiUrl + url)
        .pipe(
          catchError(error => {
             // do general error handling if necessary and throw
            throwError(error);
           })
        );
  }
}

Die Wachklasse:

import { of, Observable } from 'rxjs';
import { map, catchError } from 'rxjs/operators';

@Injectable()
export class ResolveGuard implements CanActivate {
constructor(
    private fooService: FooService ,
) { }

canActivate(): Observable<boolean> {
    return this.fooService.apiGet('my/url')
       .pipe(
         map(response => response.status === 'success'),
         catchError(error => of(false))
       );
}

ORIGINAL ANTWORT für rxjs 5.x

import { _throw } from 'rxjs/observable/throw':

constructor(private _http: HttpClient) {}

public apiGet(url: string): Observable<FooInterface> {
    return this._http
        .get<FooInterface>(this.apiUrl + url)
        .catch(error => {
          // do general error handling if necessary and throw
          _throw(error);
       });
}

Die Wachklasse:

import { of } from 'rxjs/observable/of';

@Injectable()
export class ResolveGuard implements CanActivate {
constructor(
    private _api: ApiService,
) { }

canActivate(): Observable<boolean> {
    return this._api.apiGet('my/url')
       .map(response => {
          let val = false;
          if ( response.status === 'success') {
                // Consume data here
                val = true;
          }
          return val;
        }).catch(error => {
          // consume the error maybe?
          of(false)
        });
}
12
Jota.Toledo

importiere einfach den Operator map und es wird funktionieren:

import { Observable } "rxjs/Observable"; 
import "rxjs/add/operator/map"; 

 canActivate(): Observable<boolean>{
        return this._api.apiGet('my/url').map(response => {
            if ( response.status === 'success') {
                // Consume data here
                return true;
            }
            return false;
        });
    }