Dịch vụ mới được cập nhật để sử dụng HttpClientModule và 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) {
// you could extract more info about the error if you want, e.g.:
console.log(`status: ${err.status}, ${err.statusText}`);
// errMsg = ...
}
return Observable.throw(errMsg);
}
}
// public API
public getData() : Observable<SomeClassOrInterface> {
// HttpClient.get() returns the body of the response as an untyped JSON object.
// We specify the type as SomeClassOrInterfaceto get a typed result.
return this._http.get<SomeClassOrInterface>(this.url)
.pipe(
tap(data => console.log('server data:', data)),
catchError(this.handleError('getData'))
);
}
Dịch vụ cũ, sử dụng httpModule không dùng nữa:
import {Injectable} from 'angular2/core';
import {Http, Response, Request} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/throw';
//import 'rxjs/Rx'; // use this line if you want to be lazy, otherwise:
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/do'; // debug
import 'rxjs/add/operator/catch';
@Injectable()
export class MyService {
constructor(private _http:Http) {}
private _serverError(err: any) {
console.log('sever error:', err); // debug
if(err instanceof Response) {
return Observable.throw(err.json().error || 'backend server error');
// if you're using lite-server, use the following line
// instead of the line above:
//return Observable.throw(err.text() || 'backend server error');
}
return Observable.throw(err || 'backend server error');
}
private _request = new Request({
method: "GET",
// change url to "./data/data.junk" to generate an error
url: "./data/data.json"
});
// public API
public getData() {
return this._http.request(this._request)
// modify file data.json to contain invalid JSON to have .json() raise an error
.map(res => res.json()) // could raise an error if invalid JSON
.do(data => console.log('server data:', data)) // debug
.catch(this._serverError);
}
}
Tôi sử dụng .do()( bây giờ.tap() ) để gỡ lỗi.
Khi có một lỗi máy chủ, các bodycủa Responseđối tượng tôi nhận được từ các máy chủ Tôi đang sử dụng (Lite-server) chỉ chứa văn bản, do đó là lý do tôi sử dụng err.text()trên hơn err.json().error. Bạn có thể cần phải điều chỉnh dòng đó cho máy chủ của bạn.
Nếu res.json()phát sinh lỗi vì nó không thể phân tích dữ liệu JSON, _serverErrorsẽ không nhận được Responseđối tượng, do đó là lý do để instanceofkiểm tra.
Trong này plunker, thay đổi urlđể ./data/data.junktạo ra một lỗi.
Người dùng của một trong hai dịch vụ nên có mã có thể xử lý lỗi:
@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()chức năng. Tôi đã thêm dòng nàyimport 'rxjs/Rx';thay thế. Bây giờ tất cả các nhà khai thác hoạt động đúng.