คุณมีทางเลือกบางอย่างขึ้นอยู่กับความต้องการของคุณ หากคุณต้องการจัดการข้อผิดพลาดตามคำขอให้เพิ่มcatch
คำขอของคุณ HttpInterceptor
หากคุณต้องการที่จะเพิ่มการแก้ปัญหาที่ทั่วโลกใช้
เปิดที่นี่เครื่องมือสาธิตการใช้งานสำหรับโซลูชันด้านล่าง
tl; dr
ในกรณีที่ง่ายที่สุดคุณจะต้องเพิ่ม a .catch()
หรือ a .subscribe()
เช่น:
import 'rxjs/add/operator/catch'; // don't forget this, or you'll get a runtime error
this.httpClient
.get("data-url")
.catch((err: HttpErrorResponse) => {
// simple logging, but you can do a lot more, see below
console.error('An error occurred:', err.error);
});
// or
this.httpClient
.get("data-url")
.subscribe(
data => console.log('success', data),
error => console.log('oops', error)
);
แต่มีรายละเอียดเพิ่มเติมโปรดดูด้านล่าง
วิธีการแก้ปัญหา (ภายใน): ข้อผิดพลาดในการบันทึกและส่งคืนการตอบกลับทางเลือก
หากคุณต้องการจัดการข้อผิดพลาดในที่เดียวคุณสามารถใช้catch
และส่งคืนค่าเริ่มต้น (หรือการตอบกลับที่ว่างเปล่า) แทนที่จะล้มเหลวทั้งหมด คุณไม่จำเป็นต้องใช้.map
เพียงแค่ในการแคสต์คุณสามารถใช้ฟังก์ชันทั่วไปได้ ที่มา: Angular.io - รับข้อผิดพลาดรายละเอียด
ดังนั้น.get()
วิธีการทั่วไปจะเป็นดังนี้:
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from "@angular/common/http";
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/of';
import 'rxjs/add/observable/empty';
import 'rxjs/add/operator/retry'; // don't forget the imports
@Injectable()
export class DataService {
baseUrl = 'http://localhost';
constructor(private httpClient: HttpClient) { }
// notice the <T>, making the method generic
get<T>(url, params): Observable<T> {
return this.httpClient
.get<T>(this.baseUrl + url, {params})
.retry(3) // optionally add the retry
.catch((err: HttpErrorResponse) => {
if (err.error instanceof Error) {
// A client-side or network error occurred. Handle it accordingly.
console.error('An error occurred:', err.error.message);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
console.error(`Backend returned code ${err.status}, body was: ${err.error}`);
}
// ...optionally return a default fallback value so app can continue (pick one)
// which could be a default value
// return Observable.of<any>({my: "default value..."});
// or simply an empty observable
return Observable.empty<T>();
});
}
}
การจัดการข้อผิดพลาดจะช่วยให้แอปของคุณดำเนินการต่อได้แม้ว่าบริการที่ URL จะอยู่ในสภาพไม่ดีก็ตาม
โซลูชันต่อคำขอนี้เป็นวิธีที่ดีส่วนใหญ่เมื่อคุณต้องการส่งคืนการตอบกลับเริ่มต้นเฉพาะสำหรับแต่ละวิธี แต่ถ้าคุณสนใจเฉพาะการแสดงข้อผิดพลาด (หรือมีการตอบสนองเริ่มต้นทั่วโลก) วิธีแก้ปัญหาที่ดีกว่าคือใช้ตัวสกัดกั้นตามที่อธิบายไว้ด้านล่าง
เรียกใช้plunker สาธิตการทำงานที่นี่
การใช้งานขั้นสูง: สกัดกั้นคำขอหรือการตอบกลับทั้งหมด
อีกครั้งคู่มือ Angular.ioแสดง:
คุณสมบัติหลักของการ@angular/common/http
สกัดกั้นคือความสามารถในการประกาศตัวสกัดกั้นซึ่งอยู่ระหว่างแอปพลิเคชันของคุณและแบ็กเอนด์ เมื่อแอปพลิเคชันของคุณส่งคำขอตัวสกัดกั้นจะเปลี่ยนรูปแบบก่อนที่จะส่งไปยังเซิร์ฟเวอร์และตัวสกัดสามารถเปลี่ยนการตอบสนองกลับก่อนที่แอปพลิเคชันของคุณจะเห็น สิ่งนี้มีประโยชน์สำหรับทุกอย่างตั้งแต่การตรวจสอบสิทธิ์ไปจนถึงการบันทึก
ซึ่งแน่นอนว่าสามารถใช้เพื่อจัดการข้อผิดพลาดได้ด้วยวิธีง่ายๆ ( demo plunker ที่นี่ ):
import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse,
HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/of';
import 'rxjs/add/observable/empty';
import 'rxjs/add/operator/retry'; // don't forget the imports
@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request)
.catch((err: HttpErrorResponse) => {
if (err.error instanceof Error) {
// A client-side or network error occurred. Handle it accordingly.
console.error('An error occurred:', err.error.message);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
console.error(`Backend returned code ${err.status}, body was: ${err.error}`);
}
// ...optionally return a default fallback value so app can continue (pick one)
// which could be a default value (which has to be a HttpResponse here)
// return Observable.of(new HttpResponse({body: [{name: "Default value..."}]}));
// or simply an empty observable
return Observable.empty<HttpEvent<any>>();
});
}
}
การจัดหาเครื่องสกัดกั้นของคุณ:เพียงแค่ประกาศHttpErrorInterceptor
ข้างต้นไม่ได้ทำให้แอปของคุณใช้งานได้ คุณต้องวางสายในโมดูลแอปของคุณโดยจัดให้เป็นตัวสกัดกั้นดังต่อไปนี้:
import { NgModule } from '@angular/core';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { HttpErrorInterceptor } from './path/http-error.interceptor';
@NgModule({
...
providers: [{
provide: HTTP_INTERCEPTORS,
useClass: HttpErrorInterceptor,
multi: true,
}],
...
})
export class AppModule {}
หมายเหตุ:หากคุณมีทั้งตัวดักจับข้อผิดพลาดและการจัดการข้อผิดพลาดในเครื่องโดยปกติแล้วจะไม่มีการทริกเกอร์การจัดการข้อผิดพลาดในพื้นที่เนื่องจากข้อผิดพลาดจะได้รับการจัดการโดยผู้สกัดกั้นก่อนที่จะถึงการจัดการข้อผิดพลาดในเครื่อง
เรียกใช้plunker สาธิตการทำงานที่นี่
return this.httpClient.get<type>(...)
ดีถ้าเขาต้องการที่จะได้รับอย่างเต็มที่แฟนซีเขาจะออกจากบริการของเขาชัดเจนอย่างเต็มที่: จากนั้นก็มีสถานบริการcatch...
ที่ไหนสักแห่งที่เขาใช้มันจริงๆเพราะนั่นคือจุดที่เขาจะสร้างกระแสการสังเกตและสามารถจัดการได้ดีที่สุด