Flutter从数据库获取数据无法生成目标分组结构问题求助
问题与解决方案:从数据库构建日期分组的事件Map
问题说明
原本的loadPreviousEvents()函数生成的是以日期为键、事件列表为值的Map结构,示例如下:
loadPreviousEvents() { mySelectedEvents = { "2022-09-13": [ {"eventDescp": "11", "eventTitle": "111"}, {"eventDescp": "22", "eventTitle": "22"} ], "2022-09-30": [ {"eventDescp": "22", "eventTitle": "22"} ], "2022-09-20": [ {"eventTitle": "ss", "eventDescp": "ss"} ] }; print(mySelectedEvents); }
现在需要从数据库接口获取数据并转换成相同结构,但尝试的异步代码返回的是[Instance of 'Future<GroupBy>']类型的列表,无法得到目标Map。
尝试的代码
loadPreviousEvents() async { var url = 'http://prospection.global-aeit.com/getEvents.php'; var res = await http.get(Uri.parse(url)); var response = json.decode(res.body) as List; print(response); var mySelectedEvents = (response.map((e) async => GroupBy.fromJson(e))).toList(); print(mySelectedEvents); return mySelectedEvents; }
输出结果
- 打印
response得到接口返回的原始数据:[{date: 2022-09-17, eventDescp: azerty, eventTitle: azertyui}, {date: 2022-09-17, eventDescp: 11, eventTitle: AZE}, {date: 2022-09-17, eventDescp: 22, eventTitle: 4556}, {date: 2022-09-20, eventDescp: 77, eventTitle: HHJ}, {date: 2022-09-17, eventDescp: 44, eventTitle: BYYY}] - 打印
mySelectedEvents得到的是Future对象列表:[Instance of 'Future<GroupBy>', Instance of 'Future<GroupBy>', Instance of 'Future<GroupBy>', Instance of 'Future<GroupBy>', Instance of 'Future<GroupBy>']
解决方案
问题根源
response.map((e) async => GroupBy.fromJson(e))中使用了async,导致每个map元素都是Future<GroupBy>,转成列表后自然是Future对象的集合。- 即便完成异步转换,得到的只是
GroupBy对象的列表,还需要进一步按日期分组,转换成目标Map结构。
修改后的代码
情况1:GroupBy.fromJson是同步方法
如果GroupBy.fromJson内部没有异步操作,直接去掉async,再按日期分组:
loadPreviousEvents() async { var url = 'http://prospection.global-aeit.com/getEvents.php'; var res = await http.get(Uri.parse(url)); var response = json.decode(res.body) as List; // 将接口数据转成GroupBy对象列表 var groupByItems = response.map((e) => GroupBy.fromJson(e)).toList(); // 构建目标Map:日期为键,事件列表为值 Map<String, List<Map<String, String>>> mySelectedEvents = {}; for (var item in groupByItems) { String date = item.date; // 假设GroupBy类包含date、eventTitle、eventDescp属性 Map<String, String> event = { 'eventTitle': item.eventTitle, 'eventDescp': item.eventDescp, }; // 按日期分组添加事件 if (!mySelectedEvents.containsKey(date)) { mySelectedEvents[date] = []; } mySelectedEvents[date]!.add(event); } print(mySelectedEvents); return mySelectedEvents; }
情况2:GroupBy.fromJson是异步方法
如果GroupBy.fromJson内部有异步操作(比如读取本地文件),需要用Future.wait等待所有转换完成:
loadPreviousEvents() async { var url = 'http://prospection.global-aeit.com/getEvents.php'; var res = await http.get(Uri.parse(url)); var response = json.decode(res.body) as List; // 等待所有异步转换完成,得到GroupBy对象列表 var groupByItems = await Future.wait( response.map((e) async => GroupBy.fromJson(e)).toList() ); // 构建目标Map(逻辑同同步情况) Map<String, List<Map<String, String>>> mySelectedEvents = {}; for (var item in groupByItems) { String date = item.date; Map<String, String> event = { 'eventTitle': item.eventTitle, 'eventDescp': item.eventDescp, }; if (!mySelectedEvents.containsKey(date)) { mySelectedEvents[date] = []; } mySelectedEvents[date]!.add(event); } print(mySelectedEvents); return mySelectedEvents; }
关键说明
- 先确保完成所有数据转换,得到
GroupBy对象的列表,而非Future列表。 - 通过遍历分组,将每个事件按日期归类,最终生成和原代码一致的Map结构。
内容的提问来源于stack exchange,提问作者Zana Souleymane Coulibaly
相关产品推荐
相关产品推荐

