【问题标题】:JSON deserialisation – objects nested inside an array inside an objectJSON 反序列化 – 对象嵌套在对象内部的数组中
【发布时间】:2022-01-10 21:01:18
【问题描述】:

我想反序列化一个 JSON 对象数组。我遵循了 Flutter 文档中的 this 教程。问题是,这个数组嵌套在另一个对象中,看起来像这样:

{
    "result":
    {
        "array":
        [
            {
                "id": 0,
                "name": "here goes the string"
            },
            {
                "id": 1,
                "name": "another one here"
            } ...

我一直在关注this官方教程,但遇到了一个错误:

I/flutter (28639): AsyncSnapshot(ConnectionState.done, null, Exception: NoSuchMethodError: Class '_InternalLinkedHashMap' 没有具有匹配参数的实例方法 'cast'。

I/flutter (28639):接收器:_LinkedHashMap len:2

I/flutter (28639):尝试调用:cast>()

I/flutter (28639): 发现: cast() => Map, #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:68:5)

我希望我对反序列化 JSON Map<String, dynamic> 的东西的 .result.array[] 引用不佳,尽管错误在前面出现了一行,我完全不知道是什么原因造成的。这个异常的原因可能是什么,我是否以一种好的方式引用数组?

我的应用基本上是这样的(我已经用箭头 (→) 标记了抛出异常的行:

/* [...] */

Future<List<Models.Degree>> fetchDegrees(http.Client client) async
{
  final response = await client
      .get(Uri.parse("api uri here"));

  // Using the compute function to run in a separate isolate.
  return compute(parseDegrees, response.body);
}

List<Models.Degree> parseDegrees(String responseBody)
{
→  final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();

  return parsed['result']['array'].map<Models.Degree>((json) => Models.Degree.fromJson(json)).toList();
}

/* [...] */

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: FutureBuilder<List<Models.Degree>>(
        future: fetchDegrees(http.Client()),
        builder: (context, snapshot) {
          if (snapshot.hasError) {
            print(snapshot.toString());
            return const Center(
              child: Text('An error has occurred!'),
            );
          } else if (snapshot.hasData) {
            return DegreesList(degrees: snapshot.data!);
          } else {
            return const Center(
              child: CircularProgressIndicator(),
            );
          }
        },
      ),
    );
  }
}

class DegreesList extends StatelessWidget {
  const DegreesList({Key? key, required this.degrees}) : super(key: key);

  final List<Models.Degree> degrees;

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: degrees.length,
      itemBuilder: (context, index) {
        return Text(degrees[index].name);
      },
    );
  }
}

【问题讨论】:

    标签: json flutter dart


    【解决方案1】:

    在该教程中,响应正文是:

    [
     {
        "albumId": 100,
        "id": 4999,
        "title": "in voluptate sit officia non nesciunt quis",
        "url": "https://via.placeholder.com/600/1b9d08",
        "thumbnailUrl": "https://via.placeholder.com/150/1b9d08"
      },
      {
        "albumId": 100,
        "id": 5000,
        "title": "error quasi sunt cupiditate voluptate ea odit beatae",
        "url": "https://via.placeholder.com/600/6dd9cb",
        "thumbnailUrl": "https://via.placeholder.com/150/6dd9cb"
      }
    ]
    

    jsonDecode 方法返回dynamic

    在这种情况下,类型是List&lt;dynamic&gt;。 List 有一个方法casthttps://api.dart.dev/stable/2.14.4/dart-core/List/cast.html。所以它工作正常。

    但是在你的情况下:

    {
        "result": {
            "array": [
                {
                    "id": 0,
                    "name": "here goes the string"
                },
                {
                    "id": 1,
                    "name": "another one here"
                }
            ]
        }
    }
    

    jsonDecode 返回 _InternalLinkedHashMap 并且它没有 cast 方法,所以它会抛出异常。

    你有很多选择,只是提一下:

    只需删除 .cast&lt;Map&lt;String, dynamic&gt;&gt;() 即可。

    您不必为了使用它而强制转换responseBody,因为“array”json 键的类型最后会是List&lt;dynamic&gt;,因此您可以毫无问题地使用map 方法。

    但如果你还是想投射,你可以使用

    final parsed = Map<String, dynamic>.from(jsonDecode(responseBody));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-26
      • 2014-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多