You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular服务中lat/long变量未定义问题求助(JS新手)

解决你的WeatherService坐标undefined问题

嘿,我一眼就看出问题出在哪了——异步操作的时机和变量作用域搞混啦,咱们一步步来修正:

问题根源拆解

  1. 异步操作顺序错误:navigator.geolocation.getCurrentPosition是异步方法,你调用它之后立刻打印lat和long,这时候回调函数onSuccess还没执行,自然拿不到值。
  2. 变量作用域错误:你把lat、long和onSuccess函数定义在了类的外部,这在Angular服务里不符合规范,而且服务的loc()方法根本访问不到这些变量(就算能访问,异步问题也没解决)。
  3. loc()方法依赖未就绪:当组件调用loc()时,坐标可能还没获取完成,导致URL里拼接的是undefined。

修正后的完整代码

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/observable/fromPromise';

@Injectable()
export class WeatherService { 
  private req: any;
  private lat: number;
  private long: number;

  constructor(private http: Http) { }

  // 封装获取地理位置的异步操作,返回Observable
  private getCurrentPosition(): Observable<GeolocationPosition> {
    return Observable.fromPromise(
      new Promise((resolve, reject) => {
        if (navigator.geolocation) {
          navigator.geolocation.getCurrentPosition(resolve, reject);
        } else {
          reject(new Error('Geolocation is not supported by this browser.'));
        }
      })
    );
  }

  loc(): Observable<any> {
    // 先获取坐标,再发起天气请求
    return this.getCurrentPosition()
      .map(position => {
        this.lat = position.coords.latitude;
        this.long = position.coords.longitude;
        return { lat: this.lat, long: this.long };
      })
      .switchMap(coords => {
        const url = `https://api.openweathermap.org/data/2.5/weather?lat=${coords.lat}&lon=${coords.long}&APPID=d9c05681b9c98fd7185573a204400f74&units=metric`;
        return this.http.get(url).map(response => response.json());
      });
  }
}

关键修改说明

  • 变量作用域修正:把lat和long改成服务的私有成员,确保loc()方法能正常访问。
  • 异步操作封装:用RxJS的Observable.fromPromise把原生地理位置API转换成Observable,和Angular的Http Observable无缝结合,保证操作顺序正确。
  • 请求顺序保证:loc()方法先等待坐标获取完成,再拼接URL发起天气请求,彻底避免undefined问题。
  • 错误处理:增加了地理位置不支持的错误处理,让服务更健壮。

组件中使用的注意事项

在组件中注入WeatherService并调用loc()时,记得订阅Observable来获取数据:

constructor(private weatherService: WeatherService) {}

getWeather() {
  this.weatherService.loc()
    .subscribe(weatherData => {
      console.log('天气数据:', weatherData);
      // 在这里处理天气数据
    }, error => {
      console.error('获取数据失败:', error);
    });
}

内容的提问来源于stack exchange,提问作者Shashank Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:43:13