Jac*_*r94 0 json typescript angular
所以我试图通过创建一个应用程序来学习一些基本的Angular,该应用程序使用OpenWeather API获取并显示某个位置的当前天气.
这就是我目前代码中的内容:
app.component.ts:
import { Component } from '@angular/core';
import { WeatherService } from './weather.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [WeatherService]
})
export class AppComponent {
title = 'Ng-Weather';
cityName: string;
weather: Weather;
constructor(private weather: WeatherService) { }
search() {
this.weather.getWeatherbyName(this.cityName)
.subscribe(res => this.weather = res);
console.log(this.weather);
}
}
Run Code Online (Sandbox Code Playgroud)
weather.service.ts:
import { Injectable } from '@angular/core';
import { Http, Response, URLSearchParams } from '@angular/http';
import { Observable } from 'rxjs';
import { Weather } from './weather';
@Injectable()
export class WeatherService {
APIurl = "http://api.openweathermap.org/data/2.5/weather";
Appid = "xxx";
weather: Weather;
constructor(private http: Http) { }
getWeatherbyName(name: string): Observable<any> {
let myParams = new URLSearchParams();
myParams.append('appid', this.Appid);
myParams.append('q', name);
return this.http.get(this.APIurl , { search: myParams} )
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
this.weather.city = body.name;
this.weather.description = body.weather[0].main;
this.weather.temp = body.main.temp;
console.log(this.weather);
}
private handleError(error: Response | any) {
console.error(error.message || error);
return Observable.throw(error.message || error);
}
}
Run Code Online (Sandbox Code Playgroud)
weather.ts:
export class Weather {
city: String;
description: String;
temp: String;
}
Run Code Online (Sandbox Code Playgroud)
所以基本上我试图映射从OpenWeather API返回的JSON,只获取数据的某些部分,而不是整个事物.返回的JSON如下:
{
"coord":{
"lon":80.28,
"lat":13.09
},
"weather":[
{
"id":802,
"main":"Clouds",
"description":"scattered clouds",
"icon":"03n"
}
],
"base":"stations",
"main":{
"temp":303.15,
"pressure":1008,
"humidity":79,
"temp_min":303.15,
"temp_max":303.15
},
"visibility":6000,
"wind":{
"speed":3.1,
"deg":210
},
"clouds":{
"all":40
},
"dt":1504805400,
"sys":{
"type":1,
"id":7834,
"message":0.0017,
"country":"IN",
"sunrise":1504744074,
"sunset":1504788314
},
"id":1264527,
"name":"Chennai",
"cod":200
}
Run Code Online (Sandbox Code Playgroud)
执行上面的代码时,我收到此错误:
weather.service.ts:32 Cannot set property 'city' of undefined
Run Code Online (Sandbox Code Playgroud)
另外,我如何返回类型为Weather的observable并返回该变量天气并在app.component.ts上捕获它?
在分配其属性之前,您不是在创建天气对象的实例.你可以这样明确地做到这一点:
this.weather = new Weather();
this.weather.city = body.name;
this.weather.description = body.weather[0].main;
this.weather.temp = body.main.temp;
console.log(this.weather);
Run Code Online (Sandbox Code Playgroud)
要么
你可以这样做:
this.weather = {
city: body.name,
description: body.weather[0].main,
temp: body.main.temp
}
console.log(this.weather);
Run Code Online (Sandbox Code Playgroud)
要回答问题的第二部分,您应该能够这样做:
getWeatherbyName(name: string): Observable<Weather> {
// your other code
}
private extractData(res: Response) {
// your other code
return this.weather;
}
Run Code Online (Sandbox Code Playgroud)
并回答你问题的第三部分...... Observables是异步的.这意味着它们不会立即返回值.相反,它们提供了在返回数据时执行的回调函数的定义.这意味着在返回数据并执行回调函数之前,数据是未定义的.
因此,如果要访问代码中返回的数据,则需要在WITHIN中执行回调函数.像这样:
search() {
this.weather.getWeatherbyName(this.cityName)
.subscribe(res => {
this.weather = res;
console.log(this.weather);
});
}
Run Code Online (Sandbox Code Playgroud)