What is the best way to combine two observables in Angular using RxJS?

In my service, I have the following methods:

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

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

Within my Component, these methods are utilized in the following manner:

  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 aim to use them as follows:

<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>

The return values of the calls are provided as comments in the code.

For instance, the file map-0.svg should correspond to the JSON file map-mapping-0.json. Similarly, map-1.svg should match with map-mapping-1.json.

Do the arrays returned by the calls need to be sorted for this to function correctly? As currently, they are unordered when received from the backend.

Answer №1

It's not entirely clear from your template and description what format your data should take for easy consumption. My suggestion would be to manipulate your data until it aligns with your template requirements, then utilize angular's async pipe.

// Here I'm using an array of string tuples as an example, 
// but you can adjust it to fit your needs
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'll need to create this function to properly organize/sort 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 named {{tupleData[0]}} 
    and its assetJson is called {{tupleData[1]}}
</div>

This is a simplified illustration, showcasing the basic structure of joining and formatting data before displaying it. While I used a tuple of strings in this instance, feel free to tailor it to suit your specific needs, such as implementing nested ngFor* directives for customized data display.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Angular's nested arrays can be transformed into a grid interface with ease

I am looking to generate a grid template from a nested array. The current method works well if the elements naturally have the same height, but issues arise when values are too long and some elements end up with different heights. <div id="containe ...

Typescript subtraction operation may result in Undefined

I am a beginner in the world of TypeScript and I'm currently struggling with running this code snippet: class TestClass { public t: number = 10; constructor() { this.t = this.t - 1; console.log(this.t); } } var obj = new TestClass(); ...

Dot notation for Typescript aliases

Here are the imports I have in my TypeScript source file: import {Vector as sourceVector} from "ol/source"; import {Vector} from "ol/layer"; This is how Vector is exported in ol/source: export { default as Vector } from './source/ ...

Building the Android release version of an Ionic Cordova app using the command `ionic cordova build android –prod –release` may encounter a failure when it

Having an issue with Ionic 3. Whenever I use cordova build android --prod --release, the APK shows a white screen after splash. Alternatively, when using ionic cordova build android --prod --release, I encounter the following error. https://i.stack.imgur. ...

Retrieving the URL of a previous page in a Nest.js server

In our application, we utilize Angular 8 for the user interface and Nest Js server. One challenge we are facing is that when navigating to different pages within the application, the page URL includes a port number. While I am able to access this page UR ...

Leveraging the find method to sort through an array with dual parameters

I'm facing an issue while trying to filter my array of objects using two parameters. Despite having an object in the array with the same values as the parameters, the result is empty. const item = this.lista.find(i => i.number === rule.number && ...

Unable to bind service data to the kendoUI grid

I'm in the process of developing an angular 4 component incorporating kendoUI. While using the kendoUI grid to display json data, I've encountered a debugging issue. The service seems to be retrieving records successfully, but for some reason, th ...

Issue with mui TextField label width not adjusting properly with font override

Whenever I change the font of the label, the width of the label does not adjust accordingly and the text appears to be outlined. For a demonstration, you can check out this example on CodeSandbox ...

It is not possible to alter the styles of the ng-daterangepicker Angular plugin

After installing the angular2 plugin "ng-daterangepicker", I attempted to resize a div within it by modifying the .sass file. However, despite clearing the cache, the changes did not reflect in my browser. It seems that I may need to make adjustments to .s ...

When utilizing Rx.Observable with the pausable feature, the subscribe function is not executed

Note: In my current project, I am utilizing TypeScript along with RxJS version 2.5.3. My objective is to track idle click times on a screen for a duration of 5 seconds. var noClickStream = Rx.Observable.fromEvent<MouseEvent>($window.document, &apos ...

How To Retrieve the Index of a Specific Row and Column in AgGrid (Angular)

Right now, I can retrieve the row data using the gridApi but I am struggling to determine the column index of the selected row. The method this.gridApi.getSelectedRows() does not provide any information about the column index. I would greatly appreciate ...

What is the best way to prevent updating the state before the selection of the end date in a date range using react-datepicker?

Managing user input values in my application to render a chart has been a bit tricky. Users select a start date, an end date, and another parameter to generate the chart. The issue arises when users need to edit the dates using react-datepicker. When the s ...

Tips for resolving the ExtPay TypeError when using Typscript and Webpack Bundle

I am currently trying to install ExtPay, a payment library for Chrome Extension, from the following link: https://github.com/Glench/ExtPay. I followed the instructions up until step 3 which involved adding ExtPay to background.js. However, I encountered an ...

The 'getAllByRole' property is not found in the 'Screen' type. TS2339 error

I am currently developing a web application using ReactJs for the front end. While testing the code, I encountered the following error: TypeScript error in My_project/src/unitTestUtils.tsx(79,27): Property 'getAllByRole' does not exist on type & ...

Is it possible for TypeScript to preserve the return type while consolidating multiple classes or objects of functions in a reducer method?

Describing my issue with the title was challenging, but here it is: I have several objects that follow this structure: type TUtilityFunction = {[key: string]: <T>(a: T, b: any) => T} For example: class UtilityA{ DoSomeWork = function (arg1: So ...

The variable's Ionic value is not being displayed in the HTML

I recently developed a new Ionic application and encountered an issue while attempting to display a variable value in the HTML. Without making any modifications, this is the current state of my page after creating the app. import { IonicModule } from &ap ...

What steps can be taken to fix the error message "Type circularly references itself"?

Here's an example of an issue with a predictable outcome: const actionTypes = { name: { set: "name/set", }, } as const; type ActionTypes = { [key: string]: (string | ActionTypes) }; //record value is string or ActionTypes // " ...

By implementing a custom function within the router's "redirectTo" method, we can dynamically determine the destination for redirection, effectively avoiding Ahead-of-Time (A

By implementing a function to decide where the user should be directed when the site loads, I encounter the following challenge: { path : '', redirectTo: redirector(), pathMatch: 'full' } The redirector() function returns a rout ...

Using Meteor methods in a Meteor and Ionic application: A guide

After building the web app with Meteor, I am now looking to develop a new app utilizing both Meteor and Ionic technologies. My goal is to leverage the existing Meteor methods in my Ionic app without duplicating efforts for mobile development. Any suggestio ...

The 'substr' property is not found in the type 'string | string[]'

Recently, I had a JavaScript code that was working fine. Now, I'm in the process of converting it to TypeScript. var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; if (ip.substr(0, 7) == "::ffff ...