未处理的异常:类型 'Null' 不是类型 'String' 的子类型
Unhandled Exception: type 'Null' is not a subtype of type 'String'
我正在学习 Flutter 课程(课程是在 flutter 2 之前录制的)当我 运行 遇到这个错误时:
I/flutter ( 3538): type 'Null' is not a subtype of type 'String'
E/flutter ( 3538): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: type 'Null' is not a subtype of type 'String'
E/flutter ( 3538): #0 Products.fetchAndSetProducts
package:shop_app/providers/products_provider.dart:80
E/flutter ( 3538): <asynchronous suspension>
我试着检查突出显示的行是否有问题,对我来说没问题。
代码如下:
Future<void> fetchAndSetProducts() async {
var url = Uri.parse(
'https://flutter-39ecc-default-rtdb.firebaseio.com/products.json');
try {
final response = await http.get(url);
final extractedData = json.decode(response.body) as Map<String, dynamic>;
final List<Product> loadedProducts = [];
extractedData.forEach((key, value) {
loadedProducts.add(Product(
id: key,
title: value['title'],
description: value['description'],
price: value['price'],
isFavorite: value['isFavorite'],
imageUrl: value['imageUrl']));
});
_items = loadedProducts;
notifyListeners();
// print(json.decode(response.body));
} catch (error) {
print(error);
throw error; // line 80
}
}
我就是这样调用这个函数的
var _isInit = true;
var _isLoading = false;
@override
void didChangeDependencies() {
if (_isInit) {
setState(() {
_isLoading = true;
});
Provider.of<Products>(context).fetchAndSetProducts().then((_) {
setState(() {
_isLoading = false;
});
});
}
_isInit = false;
super.didChangeDependencies();
}
请检查您的 Product
class。它的属性应该可以是Null
.
所以可能是 String?
而不是 String
Product(
id: key,
title: value['title'],
description: value['description'],
price: value['price'],
isFavorite: value['isFavorite'],
imageUrl: value['imageUrl']));
}
我查看了 https://flutter-39ecc-default-rtdb.firebaseio.com/products.json
的回复。构造 Product
对象时需要使用一些缺少的键。
发生这种情况是因为您尝试分配的值之一为空,而变量不可为空
loadedProducts.add(Product(
id: key,
title: value['title'],
description: value['description'],
price: value['price'],
isFavorite: value['isFavorite'],
imageUrl: value['imageUrl']));
});
看看这段代码,如果你想制作一个产品模型class,如果你让每个变量都可以为空就好了。
class ProductModel {
int? id;
String? title;
String? description;
double? price;
bool? isFavorite;
String? imageUrl;
}
如果你真的很小心地处理来自后端的分配,那就太好了。因为一些后端不一致。
factory ProductModel ProductModel.fromJson(Map<String, dynamic> json) => ProductModel({
id: json['id'] != null ? (json['id'] as num?)?.toInt() : null,
//it would be great if you also check if the json['id'] is instance of String or not, because sometimes you can get id with type String from backend
// why use num? instead of int?, because sometimes we can also get double from backend right? and int and double indicator isn't consistent
// that's why num? then cast to the type you want is the best practice
title: json['title'] as String?,
//etc..
});
我正在学习 Flutter 课程(课程是在 flutter 2 之前录制的)当我 运行 遇到这个错误时:
I/flutter ( 3538): type 'Null' is not a subtype of type 'String'
E/flutter ( 3538): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: type 'Null' is not a subtype of type 'String'
E/flutter ( 3538): #0 Products.fetchAndSetProducts
package:shop_app/providers/products_provider.dart:80
E/flutter ( 3538): <asynchronous suspension>
我试着检查突出显示的行是否有问题,对我来说没问题。
代码如下:
Future<void> fetchAndSetProducts() async {
var url = Uri.parse(
'https://flutter-39ecc-default-rtdb.firebaseio.com/products.json');
try {
final response = await http.get(url);
final extractedData = json.decode(response.body) as Map<String, dynamic>;
final List<Product> loadedProducts = [];
extractedData.forEach((key, value) {
loadedProducts.add(Product(
id: key,
title: value['title'],
description: value['description'],
price: value['price'],
isFavorite: value['isFavorite'],
imageUrl: value['imageUrl']));
});
_items = loadedProducts;
notifyListeners();
// print(json.decode(response.body));
} catch (error) {
print(error);
throw error; // line 80
}
}
我就是这样调用这个函数的
var _isInit = true;
var _isLoading = false;
@override
void didChangeDependencies() {
if (_isInit) {
setState(() {
_isLoading = true;
});
Provider.of<Products>(context).fetchAndSetProducts().then((_) {
setState(() {
_isLoading = false;
});
});
}
_isInit = false;
super.didChangeDependencies();
}
请检查您的 Product
class。它的属性应该可以是Null
.
所以可能是 String?
而不是 String
Product(
id: key,
title: value['title'],
description: value['description'],
price: value['price'],
isFavorite: value['isFavorite'],
imageUrl: value['imageUrl']));
}
我查看了 https://flutter-39ecc-default-rtdb.firebaseio.com/products.json
的回复。构造 Product
对象时需要使用一些缺少的键。
发生这种情况是因为您尝试分配的值之一为空,而变量不可为空
loadedProducts.add(Product(
id: key,
title: value['title'],
description: value['description'],
price: value['price'],
isFavorite: value['isFavorite'],
imageUrl: value['imageUrl']));
});
看看这段代码,如果你想制作一个产品模型class,如果你让每个变量都可以为空就好了。
class ProductModel {
int? id;
String? title;
String? description;
double? price;
bool? isFavorite;
String? imageUrl;
}
如果你真的很小心地处理来自后端的分配,那就太好了。因为一些后端不一致。
factory ProductModel ProductModel.fromJson(Map<String, dynamic> json) => ProductModel({
id: json['id'] != null ? (json['id'] as num?)?.toInt() : null,
//it would be great if you also check if the json['id'] is instance of String or not, because sometimes you can get id with type String from backend
// why use num? instead of int?, because sometimes we can also get double from backend right? and int and double indicator isn't consistent
// that's why num? then cast to the type you want is the best practice
title: json['title'] as String?,
//etc..
});