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 :)