[英]Subscribing to observable of 2 types on Angular
對不起,標題,但我找不到更好的。
我正在調用一個 HTTP API,它在發送 GET 命令時返回一個 json 對象,但如果找不到資源,它將返回 404。 我正在使用 Angular 9,我正在嘗試找到一種方法來從服務輸出 json 對象或在同一個 Observable 上返回接收到的 HTTP 錯誤的枚舉值。
請看下面的一些代碼:
getDevice(objectID: number | string): Observable<Device | ResponseStatus> {
return this.http.get<Device>(`http://localhost:8080/Registration/Device/${objectID}`)
.pipe(
catchError(this.handleError)
);
}
handleError(error: HttpErrorResponse): Observable<ResponseStatus> {
switch (error.status) {
case 404: {
return of(ResponseStatus.objectNotFound);
break;
}
case 409: {
return of(ResponseStatus.objectAlreadyExists);
break;
}
}
}
我希望將 ResponseStatus 返回給我的組件,這樣我就可以以相同的方式處理所有錯誤。
export class DeviceItemResolverService implements Resolve<Device> {
constructor(private ds: DeviceService, private router: Router) { }
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Device> | Observable<never> {
let objectID = route.paramMap.get('objectID');
return this.ds.getDevice(objectID).pipe(
take(1),
mergeMap(
(item: Device) => {
if (item) {
return of(item);
}
else {
this.router.navigate(['/devices']);
return EMPTY;
}
}
)
);
}
}
一切顯然進展順利。 運行程序我可以接收設備,但我找不到處理解析器上的 ResponseStatus 的方法。
拜托,你能幫我嗎?
不需要使用mergeMap
,因為在這種情況下map
應該足夠好。
import { map } from 'rxjs/operators';
....
return this.ds.getDevice(objectID).pipe(
take(1),
map(
(item: Device | ResponseStatus) => {
// this if statement I think is the culprit.
// Basically ResponseStatus.objectNotFound is true and it goes here
// I am not sure if instanceof will work but basically you have to find out
// if you're getting Device or ResponseStatus and act accordingly
if (item instanceof Device) {
return item;
}
else {
this.router.navigate(['/devices']);
return null;
}
}
)
);
我不能按照建議使用typeof
或instanceof
,所以我在打字稿中找到了一個關於高級類型的很棒的文檔,如下: https : //www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type -守衛
下面看看我是如何解決這個問題的:
首先我定義了一個用戶定義的類型保護:
function isDevice(value: Device | ResponseStatus): value is Device {
return (value as Device).objectID !== undefined;
}
然后我在我的原始代碼上調用了這個函數:
return this.ds.getDevice(objectID).pipe(
take(1),
mergeMap(
(item: Device | ResponseStatus) => {
if (!item) {
this.router.navigate(['/devices']);
return EMPTY;
}
else if (isDevice(item)) {
return of(item)
}
else {
switch (item as ResponseStatus) {
case ResponseStatus.objectNotFound: {
this.router.navigate(['/devices']);
return EMPTY;
}
}
}
}
)
)
}
請注意,我需要使用mergeMap
。 map
沒有用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.