Home > Enterprise >  How to reuse the observable values in CRUD methods
How to reuse the observable values in CRUD methods

Time:12-22

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'),
     ...
   )
}
  • Related