Despite my efforts to search various resources like mergeMap and switchMap, I am unable to solve the problem I'm facing as I am still new to RxJs. While I would like to provide more details about my attempts in this post, I fear it may complicate my question further.
I am currently developing a travel tracking app where users can view their trips after logging in. The frontend fetches all trip data from the backend API via http.get(). Each trip contains an array of destinations. Once the frontend receives the trip data as an observable, I intend to make additional requests to the Google Place Details API to assign a photo URL for each trip based on the destinationId of the first destination in the array.
It is important to note that all functions are working correctly except for assigning the trip ImgURL.
An example Trip object looks like this:
Trip = {
id: 1,
Title: 'Going to New York',
Members[ ... ],
Destinations: [
{
id: 'abc123', // used to obtain relevant photo from Google Place Details API
city: 'New York City',
region: 'New York',
country: 'United States'
}
],
imgURL: '' // to be assigned from Google request after fetching trips from backend
// other irrelevant properties
}
This is the method for retrieving trips:
getTrips(): Observable<Trip[]> {
return this.http.get<Trip[]>(this.tripsUrl, this.headers).pipe(
map((trips: Trip[]) =>
this.filterTripsByUsername(trips, this.auth.currentUser.username)
),
// NEED HELP HERE - mergemap? switchmap?
// goal is to assign the ImgURL for each trip using getTripImgURL()
retry(2),
catchError(this.handleError<Trip[]>('getTrips()', []))
);
}
This is the method for obtaining the imgURL as an observable:
// works fine, but open to improvements
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 (placeResult.photos.length !== 0) {
imgUrl = placeResult.photos[0].getUrl({
maxWidth: 500,
maxHeight: undefined,
});
}
obs.next(imgUrl);
obs.complete();
}
};
var PlacesService = new google.maps.places.PlacesService(
document.getElementById('empty')! as HTMLDivElement
);
PlacesService.getDetails(
{
placeId: placeId,
},
getGooglePhotoURL
);
});
}
Please keep in mind that similar functionality will be needed for individual trips when implementing getTrip().
getTrip(id: number): Observable<Trip> {
const url = `${this.tripsUrl}/${id}`;
return this.http
.get<Trip>(url, this.headers)
.pipe(
// aim is to assign the Trip's ImgURL using getTripImgURL()
retry(2),
catchError(this.handleError<Trip>('getTrip()')));
}
Thank you for your assistance. Any suggestions on improving implementation are also welcome.
My attempts with mergeMap to create subscriptions for each trip linking to getTripImgURL() did not yield the expected results due to challenges with asynchronous behavior. Mastering RxJS continues to be a learning curve given its novelty to me.