错误TypeError:无法读取未定义的属性“列表”

时间:2019-05-26 10:18:45

标签: javascript angular typescript

在尝试从API调用获取响应并在模板的响应对象中显示信息时,出现了如上所述的错误。

  

错误TypeError:无法读取未定义的属性“列表”。

在service.ts中,我正在进行服务器呼叫。我正在使用OpenWeatherMap API。

while

API返回的对象格式:

getDetails(cityName, countryCd): Observable<any>{
  return this.httpclient.get(`${this.url}${cityName},${countryCd}&APPID=${this.apiKey}`);
}

在home.component.ts中,我正在订阅服务API调用。我得到的是“对象”类型的回购。

我有一系列称为城市的对象。我正在从服务器加载响应对象,作为数组城市中每个对象的属性之一。

{"city":{"id":1851632,"name":"Shuzenji",
 "coord":{"lon":138.933334,"lat":34.966671},
 "country":"JP",
 "cod":"200",
 "message":0.0045,
 "cnt":38,
 "list":[{
    "dt":1406106000,
    "main":{
        "temp":298.77,
        "temp_min":298.77,
        "temp_max":298.774,
        "pressure":1005.93,
        "sea_level":1018.18,
        "grnd_level":1005.93,
        "humidity":87,
        "temp_kf":0.26},
    "weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}],
    "clouds":{"all":88},
    "wind":{"speed":5.71,"deg":229.501},
    "sys":{"pod":"d"},
    "dt_txt":"2014-07-23 09:00:00"}
    ]}

在home.component.html中,我正在迭代这个城市数组,并使用来自API的响应数据。数据正确显示,没有任何问题。 但是在控制台中,每次城市数组迭代时我都看到一个错误-

  

错误TypeError:无法读取未定义的属性“列表”。

this.cities = this.cityService.getCities().slice();
this.cities.forEach(element => {
  this.weatherService.getDetails(element.cityName, element.countryCd).subscribe(response => {
    element['cityWeather'] = response;});
});

我对Angular还是比较陌生,需要知道这个错误是什么以及如何解决该错误。

3 个答案:

答案 0 :(得分:1)

您的问题是您在家庭组件中引用了

<span>{{city.cityWeather.list[0].main.temp | kelvinToCelcius}} &#8451;</span>
<span>{{city.cityWeather.list[0].wind.speed | mtrPersecToKmPerhr}} km/h</span>

这些值可能不会一直定义,因此,如果未定义city.cityWeather,则访问.list属性将导致错误

  

无法读取未定义的属性“列表”。

您可以使用Angular安全导航运算符(也称为Elvis运算符)来解决此问题。

  

Angular安全导航运算符(?。)是一种流畅而便捷的方法,可防止属性路径中的null和undefined值

     

-Angular docs

通过将.更改为?.,如果Angular在对象上找不到属性,则不会抛出错误。

请注意,这仅适用于组件模板,不适用于TypeScript文件。

答案 1 :(得分:1)

尝试这样更改代码:

    <div class="col-md-4" *ngFor="let city of cities; let i = index">
        <span>{{city?.cityWeather?.list[0]?.main?.temp | kelvinToCelcius}} &#8451;</span>
        <span>{{city?.cityWeather?.list[0]?.wind?.speed | mtrPersecToKmPerhr}} km/h</span>
    </div>

这可能是由于以下事实:您的getCities()请求已完成,并且您的getDetails()调用尚未返回响应,由于代码的异步性质,该响应将在某个时间点给出。因此,当循环执行cityWeather不可用时,您将得到错误。 ?不会引发错误,但是会在可用时显示数据。

答案 2 :(得分:1)

您可以使用Angular

  

安全导航操作符(?。)

city.cityWeather?.list[0]?.main.temp
city.cityWeather?.list[0]?.wind.speed

或者您可以尝试使用Angular异步管道 https://angular.io/api/common/AsyncPipe