开发者问题收集

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

2021-05-06
885

我正在开展一个项目,我们正在使用 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 是具有某些属性的类。

然后我通过在我的 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,所以任何有关我哪里出错的帮助都将不胜感激!

2个回答

好的,参考您提供的代码 这里 ,您有 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();
}
2021-05-06

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

发生这种情况的原因是,您使用空值初始化 listOfCountries ,只有在调用订阅时(在 countryService 响应之后),才会将该值分配给 listOfCountries 属性。

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

Ihor Syrov
2021-05-06