在 Angular 中从 API 加载 json 数据时出现问题

Issues loading in json data from API in Angular

我正在开展一个项目,我们正在使用 MEAN 堆栈构建网站。我目前在前端工作,并试图从 API 中读取数据并将该数据存储在一个数组中,然后我可以访问和使用该数组。我 运行 遇到了一个非常奇怪的问题。

我的目标是加载一个包含世界上所有国家/地区的经纬度坐标的数据数组。

我有一个看起来像这样的服务:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Country } from '../models/country';

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

  REST_API_SERVER = 'http://localhost:3000/countries/getCountries';

  constructor(private httpClient: HttpClient) { }

  getCountryData() : Observable<Country[]>{

    return this.httpClient.get<Country[]>(this.REST_API_SERVER);
      
  }
}

其中 Country 是具有某些属性的 class。

然后我通过在我的 component.ts 文件中执行以下操作来访问此功能并使用它:

import { Component, OnInit, AfterViewInit, ViewChild, ElementRef, HostListener, Host } from '@angular/core';
import { Country } from '../models/country';
import { DataService } from '../services/data.service';

export class GlobeComponent implements AfterViewInit {

  listOfCountries!: Country[];

  constructor(private countryService : DataService) {
  }

ngOnInit() {
   
    this.countryService.getCountryData().subscribe((countries) => {
      this.listOfCountries = countries;
    });
} 

然后我尝试访问 listOfCountries 但无法访问。例如,如果我说:

 for (let i = 0; i < this.listOfCountries.length; i++) 

我收到以下错误:

ERROR TypeError: Cannot read property 'length' of undefined

但是,如果在 ngOnInit() 函数中包含以下行:

console.log("Country printed in ngOnInit : " + this.listOfCountries[0].Entity);

它神奇地开始工作了。但是...我收到一个新错误:

ERROR TypeError: Cannot read property '0' of undefined at GlobeComponent.ngOnInit

我真的很困惑为什么会这样。为什么 console.log 填充数组?但是为什么它继续声称数组是未定义的,即使它正在工作?在包含 console.log 之后,我可以正常访问和使用该数组。但我不想保留这个 console.log,所以任何关于我哪里出错的帮助将不胜感激!

您在两种情况下看到相同的错误。

这是因为你用一个空值初始化listOfCountries,只有当调用订阅时(在countryService 回应了)。

因此,您需要输入默认值 listOfCountries: Country[] = []; 或在读取值之前检查 listOfCountries 是否为数组。

好的,参考您提供的代码 here,您有 2 个选择:

选项 1

创建一个在值存在时调用的方法。不要依赖AfterViewInit.

listOfCountries: Country[] = [];

ngOnInit() {
   this.countryService.getCountryData().subscribe((countries) => {
     this.listOfCountries = countries;

     this.initDependencies();
   });
 }

 initDependencies() {
   this.setScene();
   this.setCamera();
   this.setRenderer();
   this.setControls();

   this.createLightGroup();
   this.createGlobe();

   this.animate();
   this.setAllPoints(this.currentYear);
 }

选项 2

仅在值存在时单独调用 this.setAllPoints(this.currentYear);

listOfCountries: Country[] = [];

ngOnInit() {
   this.countryService.getCountryData().subscribe((countries) => {
     this.listOfCountries = countries;
     
     this.setAllPoints(this.currentYear);
   });
}

ngAfterViewInit() {
   this.setScene();
   this.setCamera();
   this.setRenderer();
   this.setControls();

   this.createLightGroup();
   this.createGlobe();

   this.animate();
}