如何从API获取数组数据并将其映射到dart对象?



我试图使用Flutter文档将数组数据(来自API)映射到dart对象。该文档使用单个Json对象,而不是数组。我有以下代码:

Json数据:

[
{
"channelId" :   1
"channelTitle"  :   "Photos"
"channelImage"  :   pr01.jpg
"channelLastPost"   :   null
"lastUpdate"    :   null
"userRef"   :   1
},
{
"channelId" :   2
"channelTitle"  :   "Science"
"channelImage"  :   pr02.jpg
"channelLastPost"   :   "For test ...."
"lastUpdate"    :   "2023-01-03"
"userRef"   :   1
}
]

ChannelListModel.dart:

class ChannelListModel {
String creator;
String? image;
String title;
String lastPost;
String lastUpdate;
ChannelListModel(
{required this.creator,
required this.image,
required this.title,
required this.lastPost,
required this.lastUpdate});
factory ChannelListModel.fromJson(Map<String, dynamic> json) {
return ChannelListModel(
creator: json['userRef'],
image: json['channelImage'],
title: json['channelTitle'],
lastPost: json['channelLastPost'],
lastUpdate: json['lastUpdate']);
}
Map<String, dynamic> toJson() {
return {
"userRef" : creator,
"channelImage" : image,
"channelTitle" : title,
"channelLastPost" : lastPost,
"lastUpdate" : lastUpdate
};
}
}

HttpRequest.dart:

class HttpServices {
Future<List<ChannelListModel>> getChannelList() async {
var url = base.BaseURL.channelListUrl;
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
return List<ChannelListModel>.fromJson(jsonDecode(response.body)); //I have problem in this line
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load album');
}
}
}

ChannelPage.dart:

class _ChannelsState extends State<Channels> {
List<ChannelListModel> channels = [];
@override
void initState() {
super.initState();
channels  = getChannelsFromHttp(); // A valid array object needs to be provided here.
}
getChannelsFromHttp()async{
var httpService = HttpServices();
var result = await httpService.getChannelList();
return result;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: channels.length,
itemBuilder: (context, index) =>
ChannelCard(channelModel: channels[index]),
),
);
}
}

我想把我的代码分类,所以我决定为每个部分提供不同的dart文件。我如何修复我的代码?

代替

returnList<ChannelListModel>.fromJson(jsonDecode(response.body));

试试这个代码,

List<ChannelListModel> channels = [];
final res = jsonDecode(response.body);
channels.addAll(List<ChannelListModel>.from(
(res).map((x) => ChannelListModel.fromJson(x))));
return channels;

根据注释添加


@override
void initState() {
super.initState();
getChannelsFromHttp();
}
getChannelsFromHttp()async{
var httpService = HttpServices();
var result = await httpService.getChannelList();
setState((){
channels = result;
});
}

您的fromJson工厂返回单个ChannelListModel。你不能用List<ChannelListModel>.fromJson。相反,迭代List并将每个json转换为ChannelListModel

class HttpServices {
Future<List<ChannelListModel>> getChannelList() async {
var url = base.BaseURL.channelListUrl;
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
//return List<ChannelListModel>.fromJson(jsonDecode(response.body));
final data = jsonDecode(response.body) as List<dynamic>;
return data.map((e) => ChannelListModel.fromJson(e as Map<String, dynamic>))
.toList();
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load album');
}
}
}

可以修改ChannelListModel.fromJson方法来处理JSON对象列表而不是单个对象。这里有一种方法:

factory ChannelListModel.fromJson(List<dynamic> jsonList) {
return jsonList.map((json) => ChannelListModel(
creator: json['userRef'],
image: json['channelImage'],
title: json['channelTitle'],
lastPost: json['channelLastPost'],
lastUpdate: json['lastUpdate'])
).toList();
}

也可以使用jsonDecode将响应体转换为List,然后使用上面的方法将列表转换为ChannelListModel

final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
final jsonData = jsonDecode(response.body);
return ChannelListModel.fromJson(jsonData);
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load album');
}

还需要更新getChannelsFromHttp函数赋值的结果httpService.getChannelList()要通道变量,而不是再次调用函数。

@override
void initState() {
super.initState();
getChannelsFromHttp();
}
getChannelsFromHttp() async {
var httpService = HttpServices();
channels = await httpService.getChannelList();
setState(() {});
}

这应该能解决你代码中的问题。

最新更新