0

I am making a service call returning data from json file with a bunch of items but after get all the items i need to make another service call to get the contents of each of the items. I am using a flatmap but i am having some trouble on how to pass in a parameter - when i try it becomes underlined in the code as an error.

This is my data call:

getItems(){
    this.itemService.getItemsData().flatMap(
      data => {this.items = data;
      error => this.errorMessage = <any>error;
      return this.itemService.getItemContent();
    }).subscribe(data => {
        this.itemContent = data;
      });
  }

when i try passing into...getItemContent(this.items.contentUri) it gives me an error.

 getItemsData(){
        return this._http.get(url)
        .map((res:Response) => res.json())
        .map((obj) => Object.keys(obj).map((key)=>{return obj[key]}))
        .catch(this.handleError);
    }
 getItemContent(uri){
        return this._http.get(uri)
        .map((res:Response) => res.json())
        .catch(this.handleError);
    }

How should i properly do this so when i get items i could also make a call to get the items contents based on a parameter?

here is a sample of the json structure:

{
  Item 1: {
     title:....
     id:....
     content:{
        uri:"link"
     }
  }
}

UPDATE:

getItems(){
    this.itemService.getItemsData().flatMap(
      data => {this.items = data;
      for(let x of data){
          var url = x.content.uri;
           this.observables.push(this.itemService.getInnerItemData(url));
      }
      return Observable.forkJoin(this.observables);
    }).subscribe(data => {
        this.itemsContent = data;
      });
  }

HTML:

<div *ngFor="let item of items">
    {{item.title}}
    <div *ngFor="let content of itemsContent">
      {{content.infoText}}
    </div>
</div>

now within my display the item.title is showing appropriately as expected but the content within each item is showing up as an array of [object][object] and seems like all the itemsContent is showing up for each item and it is not specified with each itemsContent with belonging item.

bluePearl
  • 1,237
  • 4
  • 24
  • 42
  • What are you trying to accomplish here? Even if you properly use flatMap you will only get the itemContent for 1 of your items. I suppose you want to get all of the content? – eko May 16 '17 at 16:01
  • @echonax What i am trying to do here is that i have a json file to display items each of the items body content is displayed by calling another json file to display the proper info for that item (each item layout and content is different) i have made a call to get all the items and display their titles - but within the call i would like to make another call to get the body content for each of the items. – bluePearl May 16 '17 at 16:17
  • Ok then for each item you need to make an http call for the content. How are you going to achieve that with flatmap alone? You need to make http requests in a loop (for each item). Then the result should be pushed into an iterable or a string builder. Am I making sense? – eko May 16 '17 at 16:45
  • @echonax i went ahead updated my post adding a for loop to make another http within the first http call but i am not sure if it is proper format? – bluePearl May 16 '17 at 18:31

1 Answers1

1

Use forkJoin to make parallel requests.

getItems(){
    this.itemService.getItemsData().flatMap(
      data => {
      this.items = data;
      var observables = [];
      for(let x of data){
          var url = x.content.uri;
          observables.push(this.itemService.getItemContent(url));
      }
      return Observable.forkJoin(observables);
    }).subscribe(data => {
        console.log(data);
    });
}

Then in your subscribe you will see an array of response for your item contents.

Update

In your view, you can track the items' index and display that indexed items content like this:

<div *ngFor="let item of items; let i = index;">
    {{item.title}}
    <dic>
        {{itemsContent[i]?.infoText}}
    </div>
</div>
eko
  • 39,722
  • 10
  • 72
  • 98
  • Thank you! I appreciate your help - i got it working in returning the right info back but now my issue is with the view. The area of all the objects of all the items is being displayed for each item - how can i get it so that with the return each item contains its itemContent. – bluePearl May 17 '17 at 18:30
  • @bluePearl try my updated answer. I assumed you've stored your contents in a `itemsContent` field. – eko May 17 '17 at 18:36
  • It is currently showing empty divs but i am looking into that because i see data returned in the console. – bluePearl May 17 '17 at 19:18
  • @bluePearl are you assigning the data to a field? – eko May 17 '17 at 19:19
  • so when i tried `item.itemsContent[i]?.infoText` i get this error in the console: `Cannot read property '0' of undefined` – bluePearl May 17 '17 at 19:53
  • @bluePearl why did you put `item` to the front? Which array holds the content of the items? – eko May 17 '17 at 19:53
  • so i have an array for items and then an itemsContent array in which i am storing the data from the second http call (where we push the observables into) - when i display each item - i will display the title from the items array and then the context text for each item will be from the itemsContent array. – bluePearl May 17 '17 at 19:57
  • Yes. Hence, itemsContent[i] will display the ith indexed items content. Can you try like I wrote in my answer? – eko May 17 '17 at 20:03
  • you are correct it was my mistake but i still get empty divs with `itemsContent[i]?.infoText` if i try `itemsContent[i]` i see the right amount of `[object][object]` but when trying to display the text nothing shows. Would it make a difference that each array doesn't have the same naming convention. meaning they don't all have `infoText` – bluePearl May 17 '17 at 20:04
  • Well of course.. I assumed the array contains the same data structure for all of its elements.. – eko May 17 '17 at 20:05
  • 1
    i am starting to think the structure of the json file is not the best – bluePearl May 17 '17 at 20:11