简体   繁体   English

无法使用角度组件从 API 获取天气数据

[英]Can't get weather data from API using angular components

I want to create a simple weather app using angular 2, just to learn this framework.我想使用 angular 2 创建一个简单的天气应用程序,只是为了学习这个框架。

I've got GraphsComponent, where I'm going to draw temperature chart.我有 GraphsComponent,我将在其中绘制温度图表。

import { Component, OnInit } from '@angular/core';

import { WeatherAPIService } from './weatherAPI.service';

@Component({

  selector: 'my-graphs',

  template: '<h1>Charts for {{this.weatherAPIService.cityName}}</h1>',

  providers: [WeatherAPIService]
})

export class GraphsComponent implements OnInit { 

    weatherData = {};
    cityName: string = "";


    constructor(
                    private weatherAPIService: WeatherAPIService,
              ) { }

    ngOnInit(): void {
        this.weatherAPIService.getWeather("London").then(data => this.weatherData = data);
        console.log(this.weatherData);  //wrong data
      }

}

I also have a WeatherAPIService, which provides weather data:我还有一个 WeatherAPIService,它提供天气数据:

import { Injectable } from '@angular/core';


@Injectable()
export class WeatherAPIService {

    weatherData = {};
    cityName: string = "";

    getWeatherHelper (city: string) {
      var locationData = new Object();
        $.get("https://maps.googleapis.com/maps/api/geocode/json?address=" + city, function (data) {

           locationData['latitude'] = data.results[0].geometry.location.lat;  //latitude
           locationData['longitude'] = data.results[0].geometry.location.lng;  //longitude

            $.ajax({
                url: "https://api.darksky.net/forecast/[MyAPIKey]/" + locationData['latitude'] + ',' + locationData['longitude'],
                dataType: "jsonp",
                success: function (data) {
                    //alert("The temperatute in " + city + " is " + data.currently.temperature);
                    this.weatherData = data;
                    this.cityName = city;
                    console.log(data);  //good data
                    return data;
                }

            });

        }
    }

    getWeather(city: string): Promise<string[]> {
        return Promise.resolve(this.getWeatherHelper(city));
    }

  }

I want to get weather data to display it.我想获取天气数据来显示它。

In getWeatherFunction, I use 2 APIs: - Google geocoding to get latitude and longitude of the city i want weather for - DarkSky to get the weather (it requires latitude and longitude)在 getWeatherFunction 中,我使用了 2 个 API: - 谷歌地理编码来获取我想要天气的城市的纬度和经度 - DarkSky 获取天气(它需要纬度和经度)

The problem is the fact, that getting location and weather from APIs is asynchronous, so getWeatherHelper() finishes before the data is returned.问题在于,从 API 获取位置和天气是异步的,因此 getWeatherHelper() 在返回数据之前完成。

That's why I added weatherData and cityName in WeatherAPIService, but even though these variables have proper data after data from APIs is returned, cityName is not displayed in the template of GraphsComponent.这就是为什么我在 WeatherAPIService 中添加了weatherData和cityName,但是即使这些变量在APIs的数据返回后有正确的数据,cityName也没有显示在GraphsComponent的模板中。 Why is that?这是为什么? How should situations like this be handled?像这样的情况应该如何处理? Where should I actually store the information from weather API?我应该在哪里实际存储来自天气 API 的信息? In the component or in the service?在组件中还是在服务中?

As you can see, I used promise, because I thought it would get me the data after it is collected form API, but it doesn't.如您所见,我使用了 promise,因为我认为它会在从 API 收集数据后获取我的数据,但事实并非如此。

As you probably noticed, I'm really new to angular, so please try to answer in the way, that I could understand it.您可能已经注意到,我对 angular 真的很陌生,所以请尽量以我能理解的方式回答。 I know as much as I learned from official angular 2 tutorial ("Tour of heroes").我知道的和我从官方 angular 2 教程(“英雄之旅”)中学到的一样多。

Apart from you mixing in jQuery, you're losing the this context, when using function .除了你在 jQuery 中的混合之外,你在使用function时会失去this上下文。 I'd suggest using a lambda expression , which preserves said context, so you can actually save the data.我建议使用lambda 表达式,它保留所述上下文,因此您可以实际保存数据。

So instead of using所以而不是使用

function (data) {

start using a lambda , wherever you need an inline function:在需要内联函数的任何地方开始使用lambda

(data) => {

Applied to your code:应用于您的代码:

getWeatherHelper (city: string) {
  var locationData = new Object();
    $.get("https://maps.googleapis.com/maps/api/geocode/json?address=" + city, (data) => {

       locationData['latitude'] = data.results[0].geometry.location.lat;  //latitude
       locationData['longitude'] = data.results[0].geometry.location.lng;  //longitude

        $.ajax({
            url: "https://api.darksky.net/forecast/[MyAPIKey]/" + locationData['latitude'] + ',' + locationData['longitude'],
            dataType: "jsonp",
            success: (data) => {
                //alert("The temperatute in " + city + " is " + data.currently.temperature);
                this.weatherData = data;
                this.cityName = city;
                console.log(data);  //good data
                return data;
            }

        });

    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM