Search code examples
angularrxjsobservablereactive-programmingrxjs-pipeable-operators

How to call a SERVICE inside a Merge Scan when using the Reactive Approach RXJS in Angular


I am trying to use the reactive approach in my angular app and I am having trouble calling a service inside a scan. How do I do this? It seems the service returns an observable - how do I deal with this? Here is the error that I see: Type 'Observable' is not assignable to type 'SomeItemModel'.

itemsWithAdditions$ = merge(this.items$, this.saveItemAction$).pipe(
scan((acc, value) => {
  //Check if an array
  if (value instanceof Array) {

    return this.someService.someMethod(res).pipe(map(res => {
      value.forEach(item => {
        item.price = res.find(x => x.id === item.id).map(x => x.price);
      })
        
    }))
  }
  // Otherwise, add that value to the array
  else {
    acc.push(value);
    return acc;
  }
}, [] as SomeItemModel[] // this is the initial value for the array
)

);


Solution

  • I your case, you need to use mergeScan if you want to return an observable in a scan. This means, any returned value must be an observable :

    itemsWithAdditions$ = merge(this.items$, this.saveItemAction$).pipe(
      mergeScan(
        (acc, value) => {
          if (value instanceof Array) {
            return this.someService.someMethod(res).pipe( // observable here 
              map((res) => {
                // don't forget to return a value here
                value.forEach((item) => {
                  item.price = res
                    .find((x) => x.id === item.id)
                    .map((x) => x.price);
                });
              })
            );
          }
          else {
            acc.push(value);
            return of(acc); // observable here
          }
        },
        [] as SomeItemModel[] 
      )
    );
    

    NB: Don't forget to return a value in a map().