Reputation: 1
I need to get weather data for the city by unique ID. The API has it's limitation, so I need to group several requests into one.
getWeatherByCityId(cityId: number): Observable<IWeatherData> {
const cachedWeatherData = this.weatherCache.filter(
(weatherData: IWeatherData) => weatherData.id === cityId
);
this.getDebouncedDataTimer = timer(5000);
if (cachedWeatherData && cachedWeatherData.length !== 0) {
return of(cachedWeatherData[0]);
}
this.debouncedIds.push(cityId);
if (this.getDebouncedDataSubscription) {
this.getDebouncedDataSubscription.unsubscribe();
}
this.getDebouncedDataSubscription = this.getDebouncedDataByIds(cityId).pipe(
delay(5000)
).subscribe(data => data);
return this.getDebouncedDataSubscription;
}
The idea is to do only one request after 5000ms to get the weather for the several cities at once, instead of doing several requests after checking the cached data.
So getWeatherByCityId method should be called numerous of times and getDebouncedDataByIds should be called only once, not to overload an API.
The problem is that the return could be only Observable, but not Subscription. And I can't use map inside of pipe, because I can't unsubscribe in this case.
And I also should return the right value for each city in this case:
private getDebouncedDataByIds(cityId: number) {
return this.getWeatherByCityIds(debouncedIds).pipe(
map((weatherDataMultiple: HttpResponse<IWeatherDataMultiple>) => {
if (weatherDataMultiple.status === 200) {
this.weatherCache.push(...weatherDataMultiple.body.list);
return weatherDataMultiple.body.list.filter(
(weatherData: IWeatherData) => weatherData.id === cityId
)[0];
}
})
);
}
Upvotes: 0
Views: 360
Reputation: 602
There are few ways to do so. You could either map it outside the function or inside just like you did. But, the idea is not to subscribe inside the function. You can return the Observable and call the subscribe in the calling method. Observable will return subscription object that you can unsubscribe later on.
Upvotes: 1