Flutter: Parse json into object in Flutter, NoSuchMethodError: Class '_Map<String, dynamic>' has no instance method 'cast' with matching arguments

问题描述 投票:0回答:2

我一直在尝试将 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 来自 storyblok 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 代码映射到我的 Exercise 对象的不同方法,但我无法让它们中的任何一个显示在应用程序中。

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

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)
json flutter http content-management-system storyblok
2个回答
0
投票

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

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

此后还会显示转换错误。因为图片和视频不是String格式的。它们是对象。如果您想使用这些数据,他们还需要映射为模型


0
投票

在 Flutter 中必须使用

as
进行转换。像这样:
jsonDecode(jsonString) as Map<String, dynamic>
。如果您使用“Visual Studio Code”,我建议您下载“Dart Data Class Generator”扩展。这个扩展可以快速生成这个json转换。

看到你的 json。我会说

content
image
video
应该是类,供您用作
Exercise
类的属性。

使用这个 json to dart converter 看看这个实现的逻辑是什么样的

© www.soinside.com 2019 - 2024. All rights reserved.