我已經嘗試查看不同的資源以試圖解決這個問題(查看 mergeMap、switchMap 等),但無法讓自己解決我遇到的問題,并且對于 RxJs 來說還是相對較新的。我會在這篇文章的細節中涉及我的嘗試,但我認為它會過于混亂并使我的問題更加混亂。
我正在制作一個旅行跟蹤應用程式。用戶登錄后,它會將他們帶到顯示所有旅行的頁面(通過 http.get() 到我的后端 API)。每個行程物件都有一個目的地陣列。在前端將旅行作為可觀察物件接收后,我想向 Google Place Details API 發出請求,并使用該旅行目的地陣列中第一個目的地的 destinationId 為每次旅行分配一個照片 url。
注意:所有功能都正常作業(除了正確分配行程 ImgURL)
旅行看起來像這樣:
Trip = {
id: 1,
Title: 'Going to New York',
Members[ ... ],
Destinations: [
{
id: 'abc123', // this is a specific ID used for Google Place Details API request to get relevant photo
city: 'New York City',
region: 'New York',
country: 'United States'
}
],
imgURL: '' // gets assigned from Google request after trips are retrieved from backend
// other irrelevant properties
}
這是獲取行程的方法:
getTrips(): Observable<Trip[]> {
return this.http.get<Trip[]>(this.tripsUrl, this.headers).pipe(
map((trips: Trip[]) =>
this.filterTripsByUsername(trips, this.auth.currentUser.username) // this is bad practice.. I know it should be filtered from backend :(
),
// DO SOMETHING HERE? mergemap? switchmap?
// for each trip I'd like to assign the ImgURL to the result from getTripImgURL()
retry(2),
catchError(this.handleError<Trip[]>('getTrips()', []))
);
}
這是將 imgURL 作為可觀察物件回傳的方法:
// functions properly as is, but willing to change if necessary or 'better' to
getTripImgURL(placeId: string): Observable<string> {
return new Observable((obs) => {
let getGooglePhotoURL = function (placeResult: any, status: any) {
if (status != google.maps.places.PlacesServiceStatus.OK) {
obs.error(status);
} else {
var imgUrl = 'assets/images/trips/default.jpg';
// if google has any photos for the given placeId
if (placeResult.photos.length !== 0) {
imgUrl = placeResult.photos[0].getUrl({
maxWidth: 500, // at least set one or the other - mandatory
maxHeight: undefined,
});
}
obs.next(imgUrl);
obs.complete();
}
};
var PlacesService = new google.maps.places.PlacesService(
document.getElementById('empty')! as HTMLDivElement
);
PlacesService.getDetails(
{
placeId: placeId,
},
getGooglePhotoURL
);
});
}
請記住,我需要為單次旅行復制類似的功能.. getTrip()
getTrip(id: number): Observable<Trip> {
const url = `${this.tripsUrl}/${id}`;
return this.http
.get<Trip>(url, this.headers)
.pipe(
// I'd like to assign the Trip's ImgURL to the result from getTripImgURL()
retry(2),
catchError(this.handleError<Trip>('getTrip()')));
}
先感謝您。任何關于改變實施或不改變實施的意見也受到贊賞。
我嘗試使用mergeMap(對我來說是新概念)來使用給定的Trip[],并為每個訂閱getTripImgURL() 的旅行回傳一個可觀察的旅行,這將為每個trip.ImgURL 分配適當的谷歌照片url。但是 Observable/Subscription 異步行為從來沒有正常作業過。我只是不知道如何正確處理 RxJS,因為它對我來說仍然很新。
uj5u.com熱心網友回復:
我的方法是使用switchMap觸發包含ObservablesforkJoin陣列的a。getTripImgURL將forkJoin等待內部 Observables 陣列完成。
getTrips(): Observable<Trip[]> {
return this.http.get<Trip[]>(this.tripsUrl, this.headers).pipe(
map((trips: Trip[]) => {
// do your filtering here, but return the processed trips!
return trips
}),
switchMap(trips => forkJoin(trips.map(trip =>
this.getTripImgURL(trip.id).pipe(
map(imgUrl => ({ ...trip, imgUrl }))
// ^^^^^^ add imgUrl to the trip
)
))),
retry(2),
catchError(this.handleError<Trip[]>('getTrips()', []))
);
}
對于每個tripin ,trips它會呼叫getTripImgURL并添加imgUrl到trip.map
請注意您實際上trips在第一個回傳map。否則,它將通過undefined管道。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/522002.html
上一篇:如何為LineChart.js實作自定義資料集資料結構?
下一篇:輸入'可觀察的<void|PostProps[]>'不可分配給型別'Observable<PostProps[]>'
