通过在 Angular 中进行 API 调用 (8) 尝试使计数与数据匹配

By making API calls in Angular (8) trying to get the count match with the data

对某些人来说这可能看起来很愚蠢,但我的大部分困惑都是由我的沮丧造成的。

我正在从该页面对某些端点进行 API 调用:https://beacon-network.org/#/developers/api/beacon-network#bn-beacons

我能够获取数据的服务没有问题。我的 service.ts:

import {HttpClient} from '@angular/common/http';
import {Injectable} from '@angular/core';
import {Observable} from 'rxjs';
import {Organization} from './organization'; // it is an interface that has id and name
import {Beacons} from './beacons'; // it is an interface that has id and name

@Injectable({
  providedIn: 'root'
})
export class BeaconService {

  constructor(private http: HttpClient) { }

  public fetchOrganizations(): Observable<Organization[]> {
    return this.http.get<Organization[]>('https://beacon-network.org/api/organizations');
  }

  public fetchBeacons(): Observable<Beacons[]> {
    return this.http.get<Beacons[]>('https://beacon-network.org/api/beacons');
  
}

这是我的component.html

<table mat-table [dataSource]="organizations$"
       class="mat-elevation-z8">

  <ng-container matColumnDef="id">
    <th mat-header-cell *matHeaderCellDef>ID</th>
    <td mat-cell *matCellDef="let element"> {{element.id}} </td>
  </ng-container>

  <ng-container matColumnDef="name">
    <th mat-header-cell *matHeaderCellDef>Name</th>
    <td mat-cell *matCellDef="let element"> {{element.name}} </td>
  </ng-container>

  <ng-container matColumnDef="beacons">
    <th mat-header-cell *matHeaderCellDef>Beacons</th>
    <td mat-cell *matCellDef="let element"> {{beaconCount}} </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

这给了我一个 table 的 ID、名称和信标。 ID 和 Name 匹配正确。我的问题是信标(信标计数)应该有不同的数字与公司名称的正确匹配,我与 Postman 核对了这个,例如 Wellcome Trust Sanger Institute 应该 return 5. 根据我得到的名字全部得到 1、2、5 或 0。一些输出应该是 21、5、4 等

最后这是我的 component.ts:

import {Component, OnInit} from '@angular/core';
import {Observable, Subscription} from 'rxjs';
import {BeaconService} from './beacon.service';
import {Organization} from './organization';

@Component({
  selector: 'app-beacon',
  templateUrl: './beacon.component.html',
  styleUrls: ['./beacon.component.css']
})
export class BeaconComponent implements OnInit {

  organizations$: Observable<Organization[]>;
  beacon: any = {};
  displayedColumns = ['id', 'name', 'beacons'];

  organizations: Array<any>;

  organizationId: string;
  organizationName: string;
  beaconData: any = {};
  beacons: Array<any>;

  beaconCount = 0;
  organizationNameArray: Array<any> = [];


  constructor(private beaconService: BeaconService) {
    this.organizations$ = this.beaconService.fetchOrganizations();
  }

  ngOnInit() {

    this.beaconService.fetchOrganizations().subscribe((organizationData) => {
      this.organizations = organizationData;
      for (let i = 0; i < this.organizations.length; i++) {
        this.organizationId = this.organizations[i].id;
        this.organizationName = this.organizations[i].name;
        this.organizationNameArray.push(this.organizationName);
      }
      return this.organizationNameArray;
    });

    this.beaconService.fetchBeacons().subscribe(beacons => {
      let organizationNameInBeacon;
      this.beacons = beacons;
      for (const beacon of this.beacons) {
        this.beaconCount = 0;
        for (const org of this.organizations) {
          if (beacon.organization === org.name) {
            organizationNameInBeacon = beacon.organization;
            this.beaconCount++;
          }
        }
      }
      return this.beaconCount;
    });
  }
}

我的输出应该是组织的名称和正确的信标计数。我需要帮助。

响应摘要应该是这样的: 已找到:6,未找到:39,未找到 Applicable:36

我会 fork join 到响应,然后将它们匹配在一起,然后使用该可观察对象进行绑定。

export class BeaconComponent implements OnInit {
  displayedColumns = ['id', 'name', 'beacons'];
  fetching:boolean
  countedBeaconOrgs$: Observable<OrganizationBecons[]>;
  constructor(private beaconService: BeaconService) {}

  ngOnInit() {
    this.fetching = true;
    this.countedBeaconOrgs$ = forkJoin([
      this.beaconService.fetchOrganizations(),
      this.beaconService.fetchBeacons(),
    ]).pipe(
      map(([orgs, beacons]): OrganizationBecons[] => {
        const countedOrgs: OrganizationBecons[] = [];
        for (const org of orgs) {
          countedOrgs.push({
            ...org,
            beaconCount: beacons.filter((b) => b.organization == org.name)
              .length,
          });
        }
        return countedOrgs;
      }),
      tap(()=> {
          this.fetching=false;
      })
    );

  }
}
export interface OrganizationBecons extends Organization {
  beaconCount: number;
}

绑定

<table mat-table [dataSource]="countedBeaconOrgs$" class="mat-elevation-z8">
  <ng-container matColumnDef="id">
    <th mat-header-cell *matHeaderCellDef>ID</th>
    <td mat-cell *matCellDef="let element">{{ element.id }}    </td>
  </ng-container>

  <ng-container matColumnDef="name">
    <th mat-header-cell *matHeaderCellDef>Name</th>
    <td mat-cell *matCellDef="let element">{{ element.name }}</td>
  </ng-container>

  <ng-container matColumnDef="beacons">
    <th mat-header-cell *matHeaderCellDef>Beacon Count</th>
    <td mat-cell *matCellDef="let element">{{ element.beaconCount }}</td>
  </ng-container>
 <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
 <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>
<h1 *ngIf="fetching">Loading</h1>

更新了 stackblitz: https://stackblitz.com/edit/angular-vjttsn?file=src%2Fbeacon%2Fbeacon.component.ts

编辑:向请求添加丑陋的加载。