Home > Blockchain >  building rxjs pipe sequence that calls second http service to add additional data to model
building rxjs pipe sequence that calls second http service to add additional data to model

Time:11-21

Problem: I am new to RXJS and having a hard time changing a pipe that is fetching http data and saving it in store conditionally (if status is active). One of the properties of missing and I need to consume another http service on a item-by-item basis, to fetch that missing property before saving in store. No need to call the second http service on items that have active=false flag.

Example:

The 2 methods that fetch http data:

FetchHttpData1() : Observable<IMainModelType[]>

FetchHttpItemProperty(id:number) : Observable<IMissingPropertyType>

models:

interface IMainModelType {
  id:number,
  name:string,
  missingProperty:string, //always null
  active:boolean
}

interface IMissingPropertyType{
  id:number,
  missingProperty:string
}

code so far:

let myObs = this.FetchHttpData1().pipe(
  map((values) => { 
    values.forEach((singleValue) => {

      if(singleValue.active) {
        //this singleValue is being saved with a missing property and we dont want that
        //at this stage I need to response from FetchHttpItemProperty() to try and set the missing property
        this.storeSetSingle(singleValue);
      }
      
    });
  })
);

Suggestions on how to add extra steps to call this.FetchHttpItemProperty(id) and make sure the item set in this.storeSetSingle() has the missing property defined?

I know this is probably very basic, but Im struggling with this for a while now and your suggestions will be opportunities to learn. Also open to suggestions if you think the current pipe could be better built.

CodePudding user response:

const missingApi$ = (x: IMainModelType) => this.FetchHttpItemProperty(x.id).pipe(
  map(({ missingProperty }) => ({...x, missingProperty})),
  tap((val) => this.storeSetSingle(val)),
);

let myObs = this.FetchHttpData1().pipe(switchMap((arrs) => 
  forkJoin(arrs.map((x) => x.active ? missingApi$(x) : of(x)))
));

CodePudding user response:

Try something like this

let myObs = this.FetchHttpData1().pipe(
      switchMap((values: {id: number}[]) => {
          forkJoin(values.map(v => FetchHttpItemProperty(v.id))).pipe(
              map(vals => {
                  const results = values.map(val => {...val, ...vals.find(i => i.id === val.id)})
                  return results;
              }),
              tap(vals => vals.forEach(v => this.storeSetSingle(v)))
          )
      })

I'm just mentioning that is not a best practice to make an HTTP request inside looping an array, but if you don't have any control on the backend so here you go

good luck :)

  • Related