Nowa usługa została zaktualizowana do korzystania z HttpClientModule i RxJS v5.5.x :
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { catchError, tap } from 'rxjs/operators';
import { SomeClassOrInterface} from './interfaces';
import 'rxjs/add/observable/throw';
@Injectable()
export class MyService {
url = 'http://my_url';
constructor(private _http:HttpClient) {}
private handleError(operation: String) {
return (err: any) => {
let errMsg = `error in ${operation}() retrieving ${this.url}`;
console.log(`${errMsg}:`, err)
if(err instanceof HttpErrorResponse) {
console.log(`status: ${err.status}, ${err.statusText}`);
}
return Observable.throw(errMsg);
}
}
public getData() : Observable<SomeClassOrInterface> {
return this._http.get<SomeClassOrInterface>(this.url)
.pipe(
tap(data => console.log('server data:', data)),
catchError(this.handleError('getData'))
);
}
Stara usługa, która używa przestarzałego HttpModule:
import {Injectable} from 'angular2/core';
import {Http, Response, Request} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
@Injectable()
export class MyService {
constructor(private _http:Http) {}
private _serverError(err: any) {
console.log('sever error:', err);
if(err instanceof Response) {
return Observable.throw(err.json().error || 'backend server error');
}
return Observable.throw(err || 'backend server error');
}
private _request = new Request({
method: "GET",
url: "./data/data.json"
});
public getData() {
return this._http.request(this._request)
.map(res => res.json())
.do(data => console.log('server data:', data))
.catch(this._serverError);
}
}
Używam .do()
( teraz.tap()
) do debugowania.
Kiedy pojawia się błąd serwera The body
tego Response
obiektu, które otrzymuję z serwera używam (Lite-serwer) zawiera tylko tekst, stąd powód używam err.text()
powyżej zamiast err.json().error
. Może być konieczne dostosowanie tej linii do serwera.
Jeśli res.json()
wywołuje błąd, ponieważ nie może przeanalizować danych JSON, _serverError
nie otrzyma Response
obiektu, stąd przyczyna instanceof
sprawdzenia.
W tym celu plunkerzmień url
na, ./data/data.junk
aby wygenerować błąd.
Użytkownicy obu usług powinni mieć kod, który może obsłużyć błąd:
@Component({
selector: 'my-app',
template: '<div>{{data}}</div>
<div>{{errorMsg}}</div>`
})
export class AppComponent {
errorMsg: string;
constructor(private _myService: MyService ) {}
ngOnInit() {
this._myService.getData()
.subscribe(
data => this.data = data,
err => this.errorMsg = <any>err
);
}
}
throw()
funkcją.import 'rxjs/Rx';
Zamiast tego dodałem tę linię . Teraz wszystkie operatory działają poprawnie.