期望类型 'String' 的值,但得到类型 'Null' 之一
Expected a value of type 'String', but got one of the type 'Null'
import 'package:flutter/material.dart';
import 'widgets/main_widget.dart';
import 'package:http/http.dart' as http;
import 'dart:async';
import 'dart:convert';
Future<WeatherInfo> fetchWeather() async {
final zipCode = "180007";
final apiKey = "d415dc7d3cae2e2b8a722dca06eb9e88";
final requestUrl =
"http://api.openweathermap.org/data/2.5/weather?zip={zipCode},IN&units=imperial&appid={apiKey}";
final response = await http.get(Uri.parse(requestUrl));
return WeatherInfo.fromJson(jsonDecode(response.body));
}
class WeatherInfo {
final String location;
final double temp;
final double tempMin;
final double tempMax;
final String weather;
final int Humidity;
final double windspeed;
WeatherInfo(
{required this.location,
required this.temp,
required this.tempMin,
required this.tempMax,
required this.weather,
required this.Humidity,
required this.windspeed});
factory WeatherInfo.fromJson(Map<String, dynamic> json) {
return WeatherInfo(
location: json['name'],
temp: json['main']['temp'],
tempMin: json['main']['temp_min'],
tempMax: json['main']['temp_max'],
weather: json['weather']['description'],
Humidity: json['main']['humidity'],
windspeed: json['wind']['speed']);
}
}
void main() => runApp(MaterialApp(title: "Weather App", home: MyApp()));
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _MyApp();
}
}
class _MyApp extends State<MyApp> {
late Future<WeatherInfo> futureWeather;
@override
void initState() {
super.initState();
futureWeather = fetchWeather();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<WeatherInfo>(
future: futureWeather,
builder: (context, Snapshot) {
if (Snapshot.hasData) {
return MainWidget(
location: Snapshot.data!.location,
temp: Snapshot.data!.temp,
tempMin: Snapshot.data!.tempMin,
tempMax: Snapshot.data!.tempMax,
weather: Snapshot.data!.weather,
Humidity: Snapshot.data!.Humidity,
windspeed: Snapshot.data!.windspeed);
} else if (Snapshot.hasError) {
return Center(
child: Text("${Snapshot.error}"),
);
}
return CircularProgressIndicator();
}));
}
}
你应该在调用 fetchweather() 时等待
void initState() {
super.initState();
fun();
}
void fun() async {
futureWeather = await fetchWeather();
setState(() {});
}
}
我发现你的代码有两个问题:
- 如果您打算将 apiKey 和 zipCode 嵌入到 requestUrl 中,那么您必须在
{apiKey}
和 {zipCode}
. 之前使用 $
- 如果我没记错的话,你会因为空安全性而收到此错误,你可以声明
WeatherInfo
class 属性来处理空值,方法是在 ?
类型规范(例如,String?还是 double?)。
但我想如果你解决了第一个问题那么第二个解决方案就没有必要了,因为我猜你从 API 得到错误响应导致变量为空,所以打印响应您可以检查一下,不要忘记处理错误响应。
import 'package:flutter/material.dart';
import 'widgets/main_widget.dart';
import 'package:http/http.dart' as http;
import 'dart:async';
import 'dart:convert';
Future<WeatherInfo> fetchWeather() async {
final zipCode = "180007";
final apiKey = "d415dc7d3cae2e2b8a722dca06eb9e88";
final requestUrl =
"http://api.openweathermap.org/data/2.5/weather?zip={zipCode},IN&units=imperial&appid={apiKey}";
final response = await http.get(Uri.parse(requestUrl));
return WeatherInfo.fromJson(jsonDecode(response.body));
}
class WeatherInfo {
final String location;
final double temp;
final double tempMin;
final double tempMax;
final String weather;
final int Humidity;
final double windspeed;
WeatherInfo(
{required this.location,
required this.temp,
required this.tempMin,
required this.tempMax,
required this.weather,
required this.Humidity,
required this.windspeed});
factory WeatherInfo.fromJson(Map<String, dynamic> json) {
return WeatherInfo(
location: json['name'],
temp: json['main']['temp'],
tempMin: json['main']['temp_min'],
tempMax: json['main']['temp_max'],
weather: json['weather']['description'],
Humidity: json['main']['humidity'],
windspeed: json['wind']['speed']);
}
}
void main() => runApp(MaterialApp(title: "Weather App", home: MyApp()));
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _MyApp();
}
}
class _MyApp extends State<MyApp> {
late Future<WeatherInfo> futureWeather;
@override
void initState() {
super.initState();
futureWeather = fetchWeather();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<WeatherInfo>(
future: futureWeather,
builder: (context, Snapshot) {
if (Snapshot.hasData) {
return MainWidget(
location: Snapshot.data!.location,
temp: Snapshot.data!.temp,
tempMin: Snapshot.data!.tempMin,
tempMax: Snapshot.data!.tempMax,
weather: Snapshot.data!.weather,
Humidity: Snapshot.data!.Humidity,
windspeed: Snapshot.data!.windspeed);
} else if (Snapshot.hasError) {
return Center(
child: Text("${Snapshot.error}"),
);
}
return CircularProgressIndicator();
}));
}
}
你应该在调用 fetchweather() 时等待
void initState() {
super.initState();
fun();
}
void fun() async {
futureWeather = await fetchWeather();
setState(() {});
}
}
我发现你的代码有两个问题:
- 如果您打算将 apiKey 和 zipCode 嵌入到 requestUrl 中,那么您必须在
{apiKey}
和{zipCode}
. 之前使用 - 如果我没记错的话,你会因为空安全性而收到此错误,你可以声明
WeatherInfo
class 属性来处理空值,方法是在?
类型规范(例如,String?还是 double?)。
$
但我想如果你解决了第一个问题那么第二个解决方案就没有必要了,因为我猜你从 API 得到错误响应导致变量为空,所以打印响应您可以检查一下,不要忘记处理错误响应。