Flutter - JSON 反序列化数据提取到 FutureBuilder return 空值
Flutte - JSON deserialized data fetched to FutureBuilder return null value
我正在尝试 return 通过 FutureBuilder 使用来自 API 的数据获取照片的 ListView。在我的服务中将值添加到 List 并正确分配时,提取到 List Builder 的值为空。我不知道为什么将服务方法调用到 return Future return 的空列表。
我的模特:
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());
},
);
}
}
您遇到此问题的原因是您需要 return 映射函数中的解析对象。
解决方案 #1 - 将 return
关键字添加到现有代码中
return randomPhotos = (json.decode(_response.body) as List).map((i) {
return Photo.fromJson(i); // <-- added return keyword here
}).toList();
解决方案 #2 - 使用箭头定义 return
此解决方案适合您的代码,因为您没有操作映射中的照片对象或任何其他数据。
return randomPhotos = (json.decode(_response.body) as List).map((i) => Photo.fromJson(i)).toList();
两种解决方案都应该有效。选择适合您的编码风格和需求的内容。
我正在尝试 return 通过 FutureBuilder 使用来自 API 的数据获取照片的 ListView。在我的服务中将值添加到 List 并正确分配时,提取到 List Builder 的值为空。我不知道为什么将服务方法调用到 return Future return 的空列表。
我的模特:
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());
},
);
}
}
您遇到此问题的原因是您需要 return 映射函数中的解析对象。
解决方案 #1 - 将 return
关键字添加到现有代码中
return randomPhotos = (json.decode(_response.body) as List).map((i) {
return Photo.fromJson(i); // <-- added return keyword here
}).toList();
解决方案 #2 - 使用箭头定义 return
此解决方案适合您的代码,因为您没有操作映射中的照片对象或任何其他数据。
return randomPhotos = (json.decode(_response.body) as List).map((i) => Photo.fromJson(i)).toList();
两种解决方案都应该有效。选择适合您的编码风格和需求的内容。