0

New to angular and confused with the flatMap function.

export interface IProduct {
    productId: number;
    productName: string;
    versionUrl: string;
    versionObj: any;
}

product.service.ts:

First HTTP request returns array of IProduct objects. Make HTTP request for each product using the versionUrl from the product object and map the resulting object to product.versionObj.

product.versionObj ==> should be mapped to the result of each product's HTTP request.

getAllProductsWithAddlInfo(): Observable<IProduct[]> {
      return this._http.get('products.json')
             .flatMap((response: Response) => response.json())
             .flatMap((product: IProduct) => this._http.get(product.versionUrl), 
                     (product: IProduct, resp) => resp.json())   

product-list.component.ts:

products: IProduct[];

/* 
I would like to get an array of products with the additional info object 
mapped to versionObj from the http call for each product 
*/

ngOnInit(): void {
     this._productService.getAllProductsWithAddlInfo()
        .subscribe(
            products => this.products = products,
            error => this.errorMessage = <any>error);

    console.log(this.products);
}
acdcjunior
  • 132,397
  • 37
  • 331
  • 304
  • 1
    First you have to understand the different between `map` and `flatMap`. For example, `flatMap((response: Response) => response.json())` should be replaced by `map` – Harry Ninh Jul 25 '16 at 01:53
  • Sorry, i am new to angular/rx. From what i understand and reading about flatMap, i need to use flatMap to flatten the original array and use the product to get the additional info of that product. – vadlarc Jul 25 '16 at 03:24
  • .map((response: Response) => response.json()) – vadlarc Jul 25 '16 at 03:24

1 Answers1

0

You could use Observable.toArray():

getAllProductsWithAddlInfo(): Observable<IProduct[]> {
    return this._http.get(
        'products.json'
    ).flatMap(
        (response: Response) => response.json()
    ).flatMap(
      (product: IProduct) => this._http.get(product.versionUrl),
      (product: IProduct, resp) => {
        product.versionObj = resp.json();
        return product;
        // or simply: (product.versionObj = resp.json(), product)
      }
    ).toArray();
}

But change the debug function (at ngOnInit()) to print after the next event (otherwise it will print before the observer emmits any values):

ngOnInit(): void {
  this._productService.getAllProductsWithAddlInfo()
    .subscribe(
      products => {
        this.products = products;
        console.log('Products: ', this.products);     // console.log() move to here
      },
      error => this.errorMessage = <any>error
    );
}

Demo plunker here.

acdcjunior
  • 132,397
  • 37
  • 331
  • 304