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));
}
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)
});
}
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;
});
}