![](/img/trans.png)
[英]when I've tried to run my flutter in vs code it gave this error in debug console
[英]when i run my code it gives error code 400 but when i do hot refresh it shows data in console while getting data from api in flutter
當我運行我的代碼時,它會給出錯誤代碼 400,但是當我進行熱刷新時,它會在控制台中顯示數據,同時從 flutter 中的 api 獲取數據
這意味着 API 需要時間來發送數據但我的代碼沒有等待我也在使用異步等待但仍然
如果可以的話請幫忙
我在這里嘗試獲取數據
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:weather_app/services/location.dart';
import 'package:weather_app/utilities/constants.dart';
class LoadingScreen extends StatefulWidget {
@override
_LoadingScreenState createState() => _LoadingScreenState();
}
class _LoadingScreenState extends State<LoadingScreen> {
double latitude;
double longitude;
@override
void initState() {
super.initState();
getLocation();
}
void getLocation() async {
GettingLocation gettingLocation = GettingLocation();
await gettingLocation.getCurrentPosition();
lattitude = gettingLocation.latitude;
longitude = gettingLocation.longitude;
}
void getData() async {
http.Response response = await http.get(Uri.parse(
'https://api.openweathermap.org/data/2.5/weather?lat=$lattitude&lon=$longitude&appid=$apiKey'));
if (response.statusCode == 200) {
String data = response.body;
print(data);
} else {
print(response.statusCode);
}
}
@override
Widget build(BuildContext context) {
getData();
return Scaffold();
}
}
這是位置。dart
import 'package:geolocator/geolocator.dart';
class GettingLocation {
double latitude;
double longitude;
Future<void> getCurrentPosition() async {
try {
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.low);
latitude = position.latitude;
longitude = position.longitude;
} catch (e) {
print(e);
}
}
}
問題不在於 API 需要時間返回數據,問題在於異步方法執行的順序。
這是您顯示的執行順序:
initState -> build -> getData -> getLocation
因此,當 getData 執行時,getLocation 尚未執行完畢,因此緯度和經度沒有正確的值。 當您運行hot reload
時,只需再次執行build
和getData
,因此代碼可以正常工作。
解決此問題的最簡單方法是將對getLocation
的調用直接移動到getData
中,但這意味着獲取數據需要更長的時間,因為getPosition
只會在您執行getData
時開始執行。
首先,從initState
中刪除getPosition
,然后在getData
上
void getData() async {
await getLocation(); // <------ this line
http.Response response = await http.get(Uri.parse(
'https://api.openweathermap.org/data/2.5/weather?lat=$lattitude&lon=$longitude&appid=$apiKey'));
if (response.statusCode == 200) {
String data = response.body;
print(data);
} else {
print(response.statusCode);
}
}
還值得一提的是getData
和getLocation
的返回類型都是void
,這在處理異步回調時可能會產生意想不到的后果,我建議您將其替換為Future<void>
Future<void> getLocation() { ... }
Future<void> getData() { ... }
最后,正如我所說,這個解決方案有一點缺點,就是稍后會調用getLocation
,實際上這應該沒有任何問題,因為時間差異應該很小,但我仍然使用FutureBuilder
做了一個例子這將顯示getData
數據:
class LoadingScreen extends StatefulWidget {
@override
_LoadingScreenState createState() => _LoadingScreenState();
}
class _LoadingScreenState extends State<LoadingScreen> {
double latitude;
double longitude;
late Future<void> _locationFuture;
@override
void initState() {
super.initState();
_locationFuture = getLocation();
}
Future<void> getLocation() async {
GettingLocation gettingLocation = GettingLocation();
await gettingLocation.getCurrentPosition();
lattitude = gettingLocation.latitude;
longitude = gettingLocation.longitude;
}
Future<String?> getData() async {
await _locationFuture;
http.Response response = await http.get(Uri.parse(
'https://api.openweathermap.org/data/2.5/weather?lat=$lattitude&lon=$longitude&appid=$apiKey'));
if (response.statusCode == 200) {
return response.body;
print(data);
} else {
print(response.statusCode);
}
}
@override
Widget build(BuildContext context) {
return FutureBuilder<String?>(
future: getData(),
builder: (context, snapshot) {
if (snapshot.hasData) return Text(snapshot.data!);
return CircularProgressIndicator();
}
);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.