In my get resquest, i need to send the set of headerParams
, instead of calling the method to get the headerParams
how can call and store as static value?
how to insure other method to wait until the header details available? I am doing worst practice. any one help me?
here is my service ts file:
export class ForecastService extends EntityCollectionServiceBase<OpenWeatherResponse> implements OnInit {
private url = 'https://api.openweathermap.org/data/2.5/forecast';
httpUrlGenerator: any;
headersParams: any; //always underfed
constructor(serviceElementsFactory: EntityCollectionServiceElementsFactory, private http: HttpClient, private notificationService: NotificationsService) {
super('Forecast', serviceElementsFactory);
}
ngOnInit() {
this.headersParams = this.getCurrentLocation().subscribe(header => {
this.headersParams = header; //not working. undefined
});
}
override getAll(): Observable<OpenWeatherResponse[]> {
//need to avoid it
return this.getCurrentLocation().pipe(
map(coords => {
return new HttpParams()
.set('lat', String(coords.latitude))
.set('lon', String(coords.longitude))
.set('units', 'metrics')
.set('appid', '21ef99128f486ce0cb0f0612b7c2d567')
}),
switchMap(params => this.http.get<OpenWeatherResponse[]>(this.url, {params})),
map((value: any) => value.list),
mergeMap((value: OpenWeatherResponse[]) => of([...value])),
filter((value, index) => index % 8 === 0),
map(value => value)
)
}
getForecast() {
//need to avoid it
return this.getCurrentLocation()
.pipe(
map(coords => {
return new HttpParams()
.set('lat', String(coords.latitude))
.set('lon', String(coords.longitude))
.set('units', 'metrics')
.set('appid', '21ef99128f486ce0cb0f0612b7c2d567')
}),
switchMap(params => this.http.get<OpenWeatherResponse>(this.url, {params})),
pluck('list'),
mergeMap(value => of(...value)),
filter((value, index) => index % 8 === 0),
map(value => {
return {
dateString: value.dt_txt,
temp: value.main.temp
}
}),
toArray(),
share()
)
}
getCurrentLocation() {
//looking to call as a first method and need to save in variable
return new Observable<GeolocationCoordinates>(observer => {
window.navigator.geolocation.getCurrentPosition(
position => {
observer.next(position.coords);
observer.complete();
},
err => observer.error(err)
)
}).pipe(
retry(1),
tap({
next: () => this.notificationService.addSuccess('Got your location'),
error: catchError((err) => {
this.notificationService.addError('Failed to get the location');
return throwError(() => new Error(err));
})
}))
}
}
Please check my comments for my requirements.
CodePudding user response:
You can create a shared observable and add caching using shareReplay to avoid calling the api each time
headers$ = this.getCurrentLocation().pipe(
map(coords => {
return new HttpParams()
.set('lat', String(coords.latitude))
.set('lon', String(coords.longitude))
.set('units', 'metrics')
.set('appid', '21ef99128f486ce0cb0f0612b7c2d567')
}),
shareReplay(1) // caching
)
and then use it that way
getForecast() {
this.headers$.pipe(
switchMap(params => this.http.get<OpenWeatherResponse>(this.url, {params})),
pluck('list'),
...
)
}