首页 > 解决方案 > 变量未定义,因为它在 API 调用完成之前被实例化 - Angular 7

问题描述

我正在尝试创建一个天气应用程序。在接收操作视图所需的数据之前,我需要进行两个不同的 api 调用。

我创建了一个服务来进行这些 api 调用并设置全局变量以便从我的不同组件进行访问。第一个调用是地理位置 api。收到纬度和经度参数后,我可以对天气 api 进行第二次调用。

我遇到的问题是我的组件试图在我的天气 api 调用完成之前访问全局变量,从而为我呈现未定义的变量。

我尝试使用 async/await 但无法使其正常工作,并且最近发现了一个 forkJoin rxjs 方法。

目前我所做的解决方案是使用 setTimeout 函数等待大约 1 秒,然后再继续执行下一行代码。我觉得这不是最好的方法,但它确实有效。

有没有更好的方法我可以研究并尝试?

主要组件.ts

  currentlyForecast: string;

  lat: number;
  long: number;

  ngOnInit() {
    this.getGeo();
  }

  getGeo() {
    this.weather.getGeo()
      .subscribe((data: any) => {
        this.lat = data.latitude;
        this.long = data.longitude;
        this.getWeather(this.lat, this.long);
      });
  }

  getWeather(lat, long) {
    let location = { latitude: lat, longitude: long };

    this.weather.getWeather(location);
    setTimeout(() => {
      this.currentlyForecast = this.weather.currentlyForecast;
      console.log(this.currentlyForecast);
    }, 700);
  }

天气服务.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';

const httpOptions = {
  headers: new HttpHeaders({
    'Content-Type':  'application/json'
  })
};

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

  // Weather parameters
  public currentlyForecast: any;
  public dailyForecast: any;
  public hourlyForecast: any;
  public minutelyForecast: any;

  private weatherUrl = 'http://localhost:3000/weather/data';
  private geoLocationUrl = 'http://localhost:3000/weather/geo';

  constructor(private http: HttpClient) {
  }

  getGeo() {
    return this.http.get(this.geoLocationUrl);
  }

  getWeather(location) {
    return this.http.post(this.weatherUrl, location, httpOptions)
      .subscribe((data: any) => {
        console.log(data)
        this.currentlyForecast = data.currently;
        this.dailyForecast = data.daily;
        this.hourlyForecast = data.hourly;
        this.minutelyForecast = data.minutely;
      });
  }

}

标签: angular

解决方案


在您的代码中进行以下更改。:

// modify your service like below :  

 getWeather(location) {
    return this.http.post(this.weatherUrl, location, httpOptions)
      .map((data: any) => {
        console.log(data)
        // you can keep  these variables if needed here or
        // move them to component file
        this.currentlyForecast = data.currently;
        this.dailyForecast = data.daily;
        this.hourlyForecast = data.hourly;
        this.minutelyForecast = data.minutely;
        
        return  this.currentlyForecast; // returning this because you have used in componenet file
      });
  }
  
  // Now in component modify your method like below : 
  
  getWeather(lat, long) {
    let location = { latitude: lat, longitude: long };

    this.weather.getWeather(location).subscribe((result:any)=>{
       //result will contain currentlyForecast value
      this.currentlyForecast = result;
      console.log(this.currentlyForecast);
    });
  }
  
  


推荐阅读