1

In my service I have these methods:

  getMap(): any {
    return this.http.get(`someURL`);
  }

  getAssets(): any {
    return this.http.get(`someURL`);
  }

In my Component I use them like this:

  ngOnInit() {
    this.myService.getMap().subscribe(data => {
      this.map = data; // Returns ["map-1.svg", "map-0.svg"]
    });

    this.systemMapService.getAssets().subscribe(data =>  {
        this.assets = data; // Returns ["map-mapping-0.json", "map-mapping-1.json"]
    });
  }

In my template I want to use it like this:

<mat-tab-group mat-align-tabs="end">
  <div *ngFor="let item of assets; let i = index">
    <mat-tab label="{{i}}">
      <div class="container">
        <div class="map">
          <img id="img_equipment" [src]="apiUrl + '/path/to/svg/' + item">
          <a *ngFor="let link of map"
             title="{{ link.title }}"
             class="ink"
             [ngStyle]="{ left: link.left, top: link.top, width: link.width }">
          </a>
        </div>
      </div>
    </mat-tab>
  </div>
</mat-tab-group>

I provided the return values of the calls as comments in die code.

For example, the file map-0.svg should use this JSON as a mapping map-mapping-0.json. The file map-1.svg then in turn this JSON file map-mapping-1.json.

..and do the arrays that the calls return have to be sorted for it to work? Because unfortunately they are currently being returned unsorted by the backend.

Codehan25
  • 2,704
  • 10
  • 47
  • 94
  • Does this answer your question? [How to 'wait' for two observables in RxJS](https://stackoverflow.com/questions/44004144/how-to-wait-for-two-observables-in-rxjs) – jonrsharpe Oct 19 '20 at 14:34
  • *"do the arrays that the calls return have to be sorted for it to work"* - you tell us, do you want to match them by index (in which case yes) or can you do it by value (in which case not necessarily)? – jonrsharpe Oct 19 '20 at 14:34
  • @jonrsharpe As mentioned in my description, the file map-0.svg should use the map-mapping-0.json. So the number at the end of the file name is crucial. Each .svg has a specific JSON file that it works with. – Codehan25 Oct 19 '20 at 14:38
  • You might want to have a look at the rxjs operator `combineLatest` – Marek W Oct 19 '20 at 14:52
  • I'm currently trying it with combineLatest but I can't adjust it for my use case.. – Codehan25 Oct 19 '20 at 14:53

1 Answers1

0

From your template and description, it's not entirely clear what shape your data should take to make this easiest for you. Regardless, my instinct here would be to transform your data until it's easily consumed by your template and then use angular's async pipe.

// I'm making this an array of strings tuples, but it can 
// be whatever best serves your purpose
displayData = Observable<Array<[string, string]>>;
ngOnInit() {
 
  this.displayData = forkJoin({
    mapData: this.myService.getMap(),
    mapAssets: this.systemMapService.getAssets()
  }).pipe(
    map(({mapData, mapAssets}) => {
      const formattedData = mapData.map(mapInstance => {
          // You're going to have to define this function yourself
          // to effective organsize/sort/whatever your data. 
          const assetInstance = this.extractMapAsset(mapAssets, mapInstance);
          return [mapInstance, assetInstance];
      });
      return formattedData;
    })
  );
}

// In template
<div *ngFor='let tupleData of displayData | async'>
    The map is called {{tupleData[0]}} 
    and its assetJson is called {{tupleData[1]}}
</div>

This is a grossly simplified example, but it gets the basic structure. You join and format your data and then you display it in your view. In this example, it's just a tuple of strings, but it can be anything such that you view can have nested ngFor* calls displaying your data however you like.

Mrk Sef
  • 7,557
  • 1
  • 9
  • 21