如何在 CRUD 方法中重用可观察值
How to reuse the observable values in CRUD methods
在我的获取请求中,我需要发送 headerParams
的集合,而不是调用方法来获取 headerParams
如何调用和存储为静态值?
如何确保其他方法能够等到 header 详细信息可用?我正在做最坏的做法。有人帮帮我吗?
这是我的服务 ts 文件:
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));
})
}))
}
}
请查看我的评论以了解我的要求。
您可以创建一个共享的可观察对象并使用 shareReplay 添加缓存以避免每次调用 api
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
)
然后这样使用
getForecast() {
this.headers$.pipe(
switchMap(params => this.http.get<OpenWeatherResponse>(this.url, {params})),
pluck('list'),
...
)
}
在我的获取请求中,我需要发送 headerParams
的集合,而不是调用方法来获取 headerParams
如何调用和存储为静态值?
如何确保其他方法能够等到 header 详细信息可用?我正在做最坏的做法。有人帮帮我吗?
这是我的服务 ts 文件:
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));
})
}))
}
}
请查看我的评论以了解我的要求。
您可以创建一个共享的可观察对象并使用 shareReplay 添加缓存以避免每次调用 api
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
)
然后这样使用
getForecast() {
this.headers$.pipe(
switchMap(params => this.http.get<OpenWeatherResponse>(this.url, {params})),
pluck('list'),
...
)
}