HttpClientModule और 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'))
);
}
पुरानी सेवा, जिसमें उपयोग किए गए 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/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);
}
}
मैं डिबगिंग के लिए .do()
( अब.tap()
) का उपयोग करता हूं ।
जब सर्वर त्रुटि होती है, तो मैं जिस सर्वर (लाइट-सर्वर) का उपयोग कर रहा हूं उससे प्राप्त होने body
वाली Response
वस्तु में सिर्फ पाठ होता है, इसलिए इसका कारण मैं err.text()
इसके बजाय ऊपर का उपयोग करता हूं err.json().error
। आपको अपने सर्वर के लिए उस लाइन को समायोजित करने की आवश्यकता हो सकती है।
यदि res.json()
कोई त्रुटि उठाता है क्योंकि यह JSON डेटा को पार्स नहीं कर सकता है, तो _serverError
उसे Response
ऑब्जेक्ट नहीं मिलेगा , इसलिए instanceof
चेक का कारण ।
इसमें plunker, त्रुटि उत्पन्न url
करने के ./data/data.junk
लिए परिवर्तित करें ।
या तो सेवा के उपयोगकर्ताओं के पास कोड होना चाहिए जो त्रुटि को संभाल सकता है:
@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()
फंक्शन को लेकर भी यही समस्या है। मैंनेimport 'rxjs/Rx';
इसके बजाय इस लाइन को जोड़ा । अब सभी ऑपरेटर ठीक से काम करते हैं।