Flutter - 提取到 FutureBuilder 的 JSON 反序列化数据返回空值
Posted
技术标签:
【中文标题】Flutter - 提取到 FutureBuilder 的 JSON 反序列化数据返回空值【英文标题】:Flutte - JSON deserialized data fetched to FutureBuilder return null value 【发布时间】:2021-06-14 01:15:25 【问题描述】:我正在尝试通过从 API 获取的数据通过 FutureBuilder 返回照片的 ListView。在我的服务中将值添加到 List 并正确分配时,获取到 List Builder 的值是 null。我不知道为什么调用服务方法返回 Future 会返回 null 列表。
我的模特:
class Photo
String id;
String photoDesc;
String photoAuthor;
String photoUrlSmall;
String photoUrlFull;
String downloadUrl;
int likes;
Photo(
this.id,
this.photoDesc,
this.photoAuthor,
this.photoUrlSmall,
this.photoUrlFull,
this.downloadUrl,
this.likes);
Photo.fromJson(Map<String, dynamic> json)
id = json['id'];
photoDesc = json['description'] != null
? json['description']
: json['alt_description'];
photoAuthor = json['user']['name'] != null
? json['user']['name']
: json['user']['username'];
photoUrlSmall = json['urls']['small'];
photoUrlFull = json['urls']['full'];
downloadUrl = json['links']['download'];
likes = json['likes'];
我的服务:
Future<List<Photo>> getRandomData1() async
List<Photo> randomPhotos;
_response = await http.get(Uri.parse(
'$unsplashUrl/photos/random/?client_id=$_key.accessKey&count=30'));
if (_response.statusCode == 200)
return randomPhotos = (json.decode(_response.body) as List).map((i)
Photo.fromJson(i);
print(Photo.fromJson(i).id); // **i.e. printing returns proper values**
).toList();
else
print(_response.statusCode);
throw 'Problem with the get request';
我的建造者:
class RandomPhotosListView extends StatefulWidget
@override
_RandomPhotosListViewState createState() => _RandomPhotosListViewState();
class _RandomPhotosListViewState extends State<RandomPhotosListView>
final UnsplashApiClient unsplashApiClient = UnsplashApiClient();
Future _data;
ListView _randomPhotosListView(data)
return ListView.builder(
itemCount: data.length,
itemBuilder: (context, index)
return Text("$data[index]");
);
@override
void initState()
super.initState();
_data = unsplashApiClient.getRandomData1();
@override
Widget build(BuildContext context)
return FutureBuilder(
future: _data,
builder: (context, snapshot)
print(snapshot.data); // i.e. snapshot.data here is list of nulls
if (snapshot.connectionState == ConnectionState.waiting)
return Center(child: CircularProgressIndicator());
else if (snapshot.hasError)
print(snapshot.error);
return Text("error: $snapshot.error");
else if (snapshot.hasData)
return _randomPhotosListView(snapshot.data);
return Center(child: CircularProgressIndicator());
,
);
【问题讨论】:
乍一看,您的 map 函数没有返回解析的对象,这可能是问题所在。试试return Photo.fromJson(i)
或.map(i => Photo.fromJson(i)).toList()
你需要检查你的connectionState是否等于ConnectionState.done,然后检查snapshot.hasData或snapshot.error
谢谢@daddygames!这么小的事情,但我浪费了 3 小时试图解决它:D
@sdobrzan 它发生在我们所有人身上。这是 SO 的重要方面之一。如果您对我的回答感到满意,请标记为这样。编码愉快!
【参考方案1】:
您遇到此问题的原因是您需要在映射函数中返回已解析的对象。
解决方案 #1 - 将 return
关键字添加到现有代码中
return randomPhotos = (json.decode(_response.body) as List).map((i)
return Photo.fromJson(i); // <-- added return keyword here
).toList();
解决方案 #2 - 使用箭头定义回报
此解决方案适合您的代码,因为您没有操作 Photo 对象或映射中的任何其他数据。
return randomPhotos = (json.decode(_response.body) as List).map((i) => Photo.fromJson(i)).toList();
任何一种解决方案都应该有效。选择适合您的编码风格和需求的。
【讨论】:
以上是关于Flutter - 提取到 FutureBuilder 的 JSON 反序列化数据返回空值的主要内容,如果未能解决你的问题,请参考以下文章
Flutter Bloc:将 Firestore 数据提取到模型中
Flutter - 提取到 FutureBuilder 的 JSON 反序列化数据返回空值