Search code examples
angularrxjsobservableangular-services

Angular nested observable's in nested services - how to


I have an idea how to do nested observable s in the same component/service. Or how to return an observable from a service to a component. But how do I get data into my component from a service observable, that gets data from another service observable:

A simplified scenario:

I have a APIService that returns my data via observable:

export class StockAPIService {
// ...
    getProducts(): Observable<any> {     
        return this.http.get<any>(this.productsUrl);
    }
}

I would usually just use it like the following in a component:

export class ProductsComponent {
    products = {};
    ngOninit() {
        stockApiService.getProduct().subscribe(products => 
              this.products = doCalcWithProducts(products))
    }

    doCalcWithProducts() {
       // ALLOT of business logic comes here that I want to move to a service
    }
}

So I want to make a service that looks like this:

export class ProductService {
    doCalcWithProducts(): observable<any> {
        return stockApiService.getProduct().subscribe(products => 
              return doMoreCalcWithproducts(products))
    }
}

And then my component actually only looks like this:

export class ProductsComponent {
    products = {};
    ngOninit() {
        this.ProductService.doCalcWithProducts().subscribe(products => 
              this.products = products)
    }
}

...with the business logic removed, but still keeping my APIService separate from my ProductService

But I get an error Type 'Subscription' is not assignable to type 'Observable'. in the ProductService subscribe

And I have tried everything from pipe to map instead of subscribe...


Solution

  • The ProductService must return an Observable. That means that you cannot subscribe inside the doCalcWithProducts() method.

    You should pipe the stockApiService.getProduct() result through the map function. Like this:

    export class ProductService {
      doCalcWithProducts(): Observable<any> {
        return stockApiService.getProduct().pipe(
          map(products => this.doMoreCalcWithproducts(products))
        );
      }
    }