Flutter:将 json 解析为 Flutter 中的对象,NoSuchMethod错误:类 '_Map<String, dynamic>' 没有实例方法'cast'与匹配参数



我一直在尝试将json cms映射到一个flutter对象,并尝试了各种方法,这种方法似乎是迄今为止最好的,我在官方flutter文档中找到了它。我不确定是什么原因导致它不映射,但错误源于这一行:final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();是什么导致它不映射,我该如何修复它?

我的代码是:
import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class Exercise {
final String title;
final String body;
final String basecamplevel;
final String element;
late String? image;
late String? video;
Exercise(
{required this.title,
required this.body,
required this.basecamplevel,
required this.element,
this.image,
this.video});
factory Exercise.fromMap(Map<String, dynamic> json) {
return Exercise(
title: json['content']['title'] as String,
body: json['content']['body'] as String,
basecamplevel: json['content']['basecamplevel'] as String,
element: json['content']['element'] as String,
image: json['content']['image'] as String?,
video: json['content']['video'] as String?,
);
}
}
Future<List<Exercise>> fetchExercises(http.Client client) async {
final response = await client.get(Uri.parse(
'https://api.storyblok.com/v2/cdn/stories?content_type=exercise&token=ACCESS_TOKEN'));
return parseExercises(response.body);
}
List<Exercise> parseExercises(String responseBody) {
try {
final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Exercise>((json)).toList();
} catch (e) {
debugPrint(e.toString());
return [];
}
}

我的json来自storyblock CMS,看起来像这样:

{"stories":[{"name":"Fitball Balance","created_at":"2023-03-28T13:04:37.844Z","published_at":"2023-03-28T21:12:40.851Z","id":283199256,"uuid":"26f10325-d258-437e-8c78-d58ec6522d76","content":{"_uid":"73b84d96-ccf8-4738-b051-4b32dc1502d9","body":"Kneeling on big fitball and balancing trying not to touch the ground. Focus on single spot of the ground to maintain focus and balance ","image":{"id":7704374,"alt":"","name":"","focus":"","title":"","filename":"https://a.storyblok.com/f/212385/3253x4260/046c342607/59c6ea4b-e540-43e5-ae5f-92cdf6b786d7.jpeg","copyright":"","fieldtype":"asset","is_external_url":false},"title":"Fitball Balance","video":{"id":null,"alt":null,"name":"","focus":null,"title":null,"filename":"","copyright":null,"fieldtype":"asset"},"element":"Balance","component":"exercise","basecamplevel":"Level 1"},"slug":"fitball-balance","full_slug":"exercises/fitball-balance","sort_by_date":null,"position":-10,"tag_list":[],"is_startpage":false,"parent_id":282598867,"meta_data":null,"group_id":"3d738fd6-f616-452d-8eb9-0a5be54d1c71","first_published_at":"2023-03-28T13:07:16.996Z","release_id":null,"lang":"default","path":null,"alternates":[],"default_full_slug":null,"translated_slugs":null},{"name":"Air Form","created_at":"2023-03-27T12:56:19.146Z","published_at":"2023-03-28T21:13:00.416Z","id":282600170,"uuid":"50b1c58c-78f9-49ba-b283-86458d8ee306","content":{"_uid":"76562cd7-08cc-4bc3-8fba-97b46cbe5fc2","body":"The fourth elemental form learned in Freeform. Steps to learn air form ect ect","image":{"id":7690205,"alt":"","name":"","focus":"","title":"","filename":"https://a.storyblok.com/f/212385/750x1624/7ad9935aca/3b9f2bfb-3dc3-48b7-9aff-25077d1f6620.png","copyright":"","fieldtype":"asset","is_external_url":false},"title":"Air Form","video":{"id":null,"alt":null,"name":"","focus":null,"title":null,"filename":"","copyright":null,"fieldtype":"asset"},"element":"Air","component":"exercise","basecamplevel":"level 4"},"slug":"air-form","full_slug":"exercises/air-form","sort_by_date":null,"position":0,"tag_list":[],"is_startpage":false,"parent_id":282598867,"meta_data":null,"group_id":"60fd3a0f-57cb-41eb-bcaa-53c0e216f540","first_published_at":"2023-03-27T13:00:54.592Z","release_id":null,"lang":"default","path":null,"alternates":[],"default_full_slug":null,"translated_slugs":null}],"cv":1680037980,"rels":[],"links":[]}

我已经尝试了将json代码映射到我的锻炼对象的不同方法,但我不能让它们中的任何一个显示在应用程序中。

当我运行代码时,这是我得到的输出:

I/flutter (26561): NoSuchMethodError: Class '_Map<String, dynamic>' has no instance method 'cast' with matching arguments.
I/flutter (26561): Receiver: _Map len:4
I/flutter (26561): Tried calling: cast<Map<String, dynamic>>()
I/flutter (26561): Found: cast<Y0, Y1>() => Map<Y0, Y1>
I/flutter (26561): AsyncSnapshot<List<Exercise>>(ConnectionState.done, [], null, null)

您试图将jsonDecode的输出处理为List,但实际上返回Map,因此您必须使用stories来管理对象列表。

List<Exercise> parseExercises(String responseBody) {
try {
final parsed = (jsonDecode(responseBody)['stories'] as List).cast<Map<String, dynamic>>();
return parsed.map<Exercise>((json) => Exercise.fromJson(json)).toList();
} catch (e) {
debugPrint(e.toString());
return [];
}
}

您必须使用as在Flutter中转换。像这样:jsonDecode(jsonString) as Map<String, dynamic>。如果您使用"Visual Studio code";我建议你下载"Dart Data Class generator"。扩展。这个扩展可以快速生成json转换。

看到你的json。我想说的是,contentimagevideo应该是你可以用作Exercise类属性的类。

使用这个json到dart转换器,看看这个实现的逻辑是什么样子的

您可以使用以下代码来解析数据

return (parsed['stories'] as List).map((e) => Exercise.fromMap(e)).toList();

之后还会显示强制转换错误。因为图像和视频不是字符串格式。它们是对象。如果您想使用这些数据,它们还需要映射为模型

相关内容