[英]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
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 获取数据
it means API needs time to send data but my code is not waiting I am using async await too but still这意味着 API 需要时间来发送数据但我的代码没有等待我也在使用异步等待但仍然
please help if u can如果可以的话请帮忙
here im trying to fetch data我在这里尝试获取数据
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();
}
}
This is location.dart这是位置。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);
}
}
}
The problem is not that the API needs time to return data, the problem is the order in which asynchronous methods execute.问题不在于 API 需要时间返回数据,问题在于异步方法执行的顺序。
This is the order of execution for what you show:这是您显示的执行顺序:
initState -> build -> getData -> getLocation
So by the time getData executes, getLocation is not done executing, so latitude and longitude don't have the correct values.因此,当 getData 执行时,getLocation 尚未执行完毕,因此纬度和经度没有正确的值。 When you run
hot reload
, only build
and getData
execute again, so the code works.当您运行
hot reload
时,只需再次执行build
和getData
,因此代码可以正常工作。
The simplest way to fix this is to move the call to getLocation
into getData
directly, but this means the data will take longer to fetch because the getPosition
will only start executing when you execute getData
.解决此问题的最简单方法是将对
getLocation
的调用直接移动到getData
中,但这意味着获取数据需要更长的时间,因为getPosition
只会在您执行getData
时开始执行。
First, remove getPosition
from initState
, then, on 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);
}
}
It is also worth mentioning that both getData
and getLocation
have a return type of void
, this can have unexpected consequences when dealing with async callbacks, I recommend you replace it with Future<void>
还值得一提的是
getData
和getLocation
的返回类型都是void
,这在处理异步回调时可能会产生意想不到的后果,我建议您将其替换为Future<void>
Future<void> getLocation() { ... }
Future<void> getData() { ... }
Finally, as I said this solution has the slight disadvantage that the call to getLocation
is moved into later, in practice there shouldn't be any problem with this, because the difference in time should be minuscule, but still I made an example using FutureBuilder
that will display the getData
data:最后,正如我所说,这个解决方案有一点缺点,就是稍后会调用
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.