简体   繁体   中英

I want to show related data together from different APIs

I have two APIs:

component.ts

ngOnInit(): void {
       this.getQueryCountriesList().subscribe(arg => {
         this.countryDatas = arg;
       });
       this.getQueryNights().subscribe(obj => {
        this.nightDatas = obj;
      });
........
......
  getQueryCountriesList(){
    return this.http.get<any>(this.APIUrl + "/Visitor?tourType="+ this.tourType +"&year=" + this.selectedYear + "&month=" + this.selectedMonth +"&gender=" + this.selectedGender + "&age="+this.selectedAge);
  }
  getQueryNights(){
    return this.http.get<any>(this.APIUrl + "/Nights?tourType="+ this.tourType +"&year=" + this.selectedYear + "&month=" + this.selectedMonth +"&gender=" + this.selectedGender + "&age="+this.selectedAge);
  }

each data have same id, I want to show visits(from first API) and nights(second API) next to each other in table: component.html

<tr *ngFor="let country of countryDatas; let nights; of: nightDatas">
    <th [id]="country.countryId + '1'">{{ country.countryNameGe }}</th>
    <td [id]="country.countryId + '2'">{{ country.value }}</td>
    <td [id]="country.countryId + '3'">{{ nights.value }}</td>
</tr>

with the following code I get only nights or only visits in every column randomly

Try to use Promise.all() to wait for the two api to return response, it can be helpful.

You can use the rxJS's power. In this case, you can use forkJoin .

import { forkJoin } from 'rxjs';


ngOnInit(): void {
  forkJoin({
    countries: this.getQueryCountriesList(),
    nights: this.getQueryNights()
  }).subscribe(({countries, nights}) => {
      this.countryDatas = countries;
      this.nightDatas = nights;
  });

So, what is happing here? With forkJoin you are waiting that both observables from your API to be emitted, then emit an object that contains your data.

You can use the rxjs combineLatest operator that will wait for both observables to emit at least one value. And from there, build your array that contains both values:

import { combineLatest } from 'rxjs';
 
ngOnInit(): void {
    queryCountriesList$ = this.getQueryCountriesList();
    queryNights$ = this.getQueryNights();
     combineLatest([queryCountriesList$,queryNights$])
    .subscribe(([queryCountriesList, queryNights]) => 
    {
        // create your object here 
    }
}

Use combineLatest from RxJS operators. Visit https://rxjs.dev/api/index/function/combineLatest

import { combineLatest, of } from 'rxjs';
import { map } from 'rxjs/operators';

const weight = of(70, 72, 76, 79, 75);
const height = of(1.76, 1.77, 1.78);
const bmi = combineLatest([weight, height]).pipe(
  map(([w, h]) => w / (h * h)),
);
bmi.subscribe(x => console.log('BMI is ' + x));

// With output to console:
// BMI is 24.212293388429753
// BMI is 23.93948099205209
// BMI is 23.671253629592222

In your case:

const combined = combineLatest([
  getQueryCountriesList(),
  getQueryNights(),
]).pipe(
  map(([countries, nights]) => {
    // your logic to combine object, make sure to return the final value
  })
);
combined.subscribe((x) => console.log("Final result is " + x));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM