我正在使用OpenWeatherMap API开发天气应用程序,由于请求过多,我已经两次封锁了我的服务。我检查了我的代码很多次,找不到一个会引起服务器循环需求的地方,我检查了控制台,它给出了以下错误:错误TypeError:ctx.amindiDGES是undefined。
我在main.component.html的两行中得到此错误:
MainComponent_Template main.component.html:8
getLocation main.component.ts:39
ngOnInit main.component.ts:27
这就是我的服务今天的样子。
import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class TodayService {
url = 'http://api.openweathermap.org/data/2.5/weather';
apiKey = '***********************';
constructor(private http: HttpClient) { }
daitriecoordinatebi(lat, lon) {
let params = new HttpParams()
.set('lat', lat)
.set('lon', lon)
.set('units', 'metric')
.set('appid', this.apiKey)
return this.http.get(this.url, { params });
这是我的main.component.ts
import { Component, OnInit } from '@angular/core';
import { TodayService } from './today.service';
@Component({
selector: 'app-main',
templateUrl: './main.component.html',
styleUrls: ['./main.component.scss']
})
export class MainComponent implements OnInit {
lat;
lon;
amindiDGES;
kvirisdgeToday;
ikonkaToday;
title = 'Day1';
today = new Date();
constructor(private todayService: TodayService) { }
ngOnInit(): void {
// lokacia
this.getLocation();
// zusti saati
this.today = new Date();
}
getLocation() {
if ("geolocation" in navigator) {
navigator.geolocation.watchPosition((success) => {
this.lat = success.coords.latitude;
this.lon = success.coords.longitude;
this.todayService.daitriecoordinatebi(this.lat, this.lon).subscribe(data => {
this.amindiDGES = data;
})
})
}
}
}
这是我的main.component.html的一部分
<table>
<tbody>
<tr>
<td><i class="fas fa-wind"></i></td>
<td> Wind - {{amindiDGES.wind.speed}}</td>
</tr>
<tr>
<td><i class="far fa-eye"></i></td>
<td> Visibility - {{amindiDGES.visibility}}</td>
</tr>
<tr>
<td><i class="fas fa-tachometer-alt"></i></td>
<td> Preassure - {{amindiDGES.main.pressure}}</td>
</tr>
<tr>
<td><i class="fas fa-tint"></i></td>
<td> Humidity - {{amindiDGES.main.humidity}}</td>
</tr>
</tbody>
</table>
所有这一切中有趣的是,我从服务器获取数据并且看到了结果,但是由于需求过多,该应用在几次使用后被阻止,允许量为每分钟60个,我的应用需要800+每分钟请求数,除此之外,控制台中始终存在错误:错误TypeError:ctx.amindiDGES未定义
我的猜测是,应用程序可能会以某种方式尝试在通过服务器获取数据之前尝试显示数据,在控制台中显示错误,此后,它会反复发出多个请求,直到API被阻止。
我想知道您是否在数据获取方面有这样的问题
好吧,以下功能存在一些严重问题:
getLocation() {
if ("geolocation" in navigator) {
navigator.geolocation.watchPosition((success) => {
this.lat = success.coords.latitude;
this.lon = success.coords.longitude;
this.todayService.daitriecoordinatebi(this.lat, this.lon).subscribe(data => {
this.amindiDGES = data;
})
})
}
}
如文件所述:
Geolocation方法watchPosition()方法用于注册一个处理程序函数,该函数将在每次设备位置更改时自动调用。
因此,daitriecoordinatebi
每次位置更改时,您的代码将可观察到。因此,如果位置更改了3次,则您将有3个订阅。因此,您将调用API 3次...
您可以通过多种选择来解决此问题。
- 使用
toPromise
然后等待结果
async (success) => {
this.amindiDGES = await
this.todayService.daitriecoordinatebi(this.lat, this.lon).toPromise();
// or you can use
await lastValueFrom(this.todayService.daitriecoordinatebi(this.lat, this.lon))
// since toPromise will be deprecated
})
first
在管道中使用运算符使订阅自动销毁
this.todayService.daitriecoordinatebi(this.lat, this.lon).pipe(first()).subscribe...
// or you can use take(1)
- 您可以使用
Subject
和mergeMap
运算符来使其更优雅
positionChanged = new Subject();
getLocation() {
if ("geolocation" in navigator) {
navigator.geolocation.watchPosition((success) => {
this.lat = success.coords.latitude;
this.lon = success.coords.longitude;
this.positionChanged.next();
})
}
this.positionChanged.pipe(
mergeMap(()=>this.todayService.daitriecoordinatebi(this.lat, this.lon)))
.subscribe(data => {
this.amindiDGES = data;
})
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句