当前位置: 首页 > 知识库问答 >
问题:

错误:获取JSON时,列表不是Map类型的子类型

严元白
2023-03-14

我正在使用flatter构建一个事件应用程序,它从Rails api获取数据并显示其细节。我犯了与这个问题相同的错误,并且已经尝试了“kapsid”的答案,但还不能解决。

我的模型类(evento.dart)。基本上,它代表一个较大的事件,其中包含多个小事件。

import 'package:flutter/material.dart';    

class Evento {
  int id;
  String titulo, descricao, inicio, fim, dataFimInscricao;
  List<Evento> children;

  Evento(
      {this.id,
      this.titulo,
      this.descricao,
      this.inicio,
      this.fim,
      this.dataFimInscricao,
      this.children});

  factory Evento.fromJson(Map<String, dynamic> json) {
    var list = json['children'] as List;
    List<Evento> childrenList = list.map((c) => Evento.fromJson(c)).toList();

    return new Evento(
      id: json['id'],
      titulo: json['titulo'],
      descricao: json['descricao'],
      inicio: json['inicio'],
      fim: json['fim'],
      dataFimInscricao: json['data_fim_inscricao'],
      children: childrenList
    );
  }

main.dart列举各种类似的大型活动

import 'dart:convert';

import 'package:eventos_app/detalhesEvento.dart';
import 'package:eventos_app/model/evento.dart';
import 'package:eventos_app/utils/utils.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

void main() => runApp(new MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Future<Evento> futureEvento;

  @override
  void initState() {
    super.initState();
    futureEvento = fetchEvento();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: FutureBuilder(
          future: futureEvento,
          builder: (context, snapshot) {
            if (!snapshot.hasData) {
              print(snapshot.error);
              return Padding(
                padding: EdgeInsets.all(16),
                child: Center(
                  child: Text(snapshot.error.toString()),
                ),
              );
            } else {
              var eventos = json.decode(snapshot.data.toString());

              return ListView.builder(
                itemCount: eventos.length,
                itemBuilder: (BuildContext context, int index) {
                  return Card(
                    margin: EdgeInsets.all(8),
                    elevation: 5,
                    child: ListTile(
                      contentPadding: EdgeInsets.all(8),
                      leading: Icon(
                        Icons.local_florist,
                        size: 35,
                      ),
                      title: Text(eventos[index]['titulo']),
                      subtitle: Text(
                          'Data: ${parseDate(eventos[index]['inicio'])}\n${eventos[index]['endereco']}'),
                      onTap: () {
                        var evento = Evento.fromJson(eventos[index]);
                        print(evento.titulo);
                        Navigator.push(
                            context,
                            MaterialPageRoute(
                                builder: (context) =>
                                    DetalhesEvento(evento: evento)));

                        // Scaffold.of(context).showSnackBar(SnackBar(
                        //   content: Text('${event.title} tapped!'),
                        //   duration: new Duration(seconds: 1)
                        // ));
                      },
                    ),
                  );
                },
              );
            } // else
          },
        ),
      ),
    );
  }
}

Future<Evento> fetchEvento() async {
  final response =
      await http.get('https://api.myjson.com/bins/1d8142');

  print('----------------------------------------\n');
  print(response.body);
  print('\n----------------------------------------');

  if (response.statusCode == 200) {
    // If the server did return a 200 OK response,
    // then parse the JSON.
//    return Evento.fromJson2(json.decode(response.body));
    return Evento.fromJson(json.decode(response.body));
  } else {
    // If the server did not return a 200 OK response,
    // then throw an exception.
    throw Exception('Failed to load events');
  }
}

这是示例JSON

[
  {
    "id": 1,
    "titulo": "MAIN EVENT",
    "descricao": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In elementum metus erat. Morbi sit amet pellentesque elit. Sed at gravida nisi. In in diam in mi gravida iaculis. Phasellus ac leo vel arcu faucibus porta at nec elit. Proin imperdiet leo congue, mattis nunc non, laoreet turpis. Morbi sed faucibus lorem.",
    "inicio": "2020-03-13T10:00:00.000-03:00",
    "fim": "2020-03-31T23:59:00.000-03:00",
    "data_fim_inscricao": "2020-03-31T23:59:00.000-03:00",
    "children": [
      {
        "id": 4,
        "titulo": "SECONDARY EVENT AAA",
        "descricao": "AAAAA",
        "inicio": "2020-03-24T08:00:00.000-03:00",
        "fim": "2020-03-25T18:00:00.000-03:00",
        "data_fim_inscricao": "2020-03-23T08:00:00.000-03:00",
        "children": [

        ]
      },
      {
        "id": 3,
        "titulo": "SECONDARY EVENT BBB",
        "descricao": "BBBBB",
        "inicio": "2020-03-13T23:59:00.000-03:00",
        "fim": "2020-03-25T23:59:00.000-03:00",
        "data_fim_inscricao": "2020-03-13T23:59:00.000-03:00",
        "children": [

        ]
      },
      {
        "id": 2,
        "titulo": "SECONDARY EVENT CCC",
        "descricao": "CCCCC",
        "inicio": "2020-03-14T10:00:00.000-03:00",
        "fim": "2020-03-16T23:59:00.000-03:00",
        "data_fim_inscricao": "2020-03-16T23:59:00.000-03:00",
        "children": [

        ]
      }
    ]
  }
]

我做错了什么??

共有1个答案

微生俊健
2023-03-14

问题是您从预期的数据接收方式接收到的数据之间不匹配。具体来说,您正试图传递响应。具有的正文类型为<代码>列表

我不能运行你的代码,但看起来问题发生在FetchEvento的这一行:

return Evento.fromJson(json.decode(response.body)); // <-- you're passing List<dynamic>

因为你在传递回应。类型为<代码>列表的正文

factory Evento.fromJson(Map<String, dynamic> json) {  //<-- you defined json as Map<String,dynamic>

因为dart是一种强类型语言,所以必须将它们定义为相同的类型。

最简单的解决方案要么是三件事之一: 1。最简单的方法是将收到的变量类型更改为:

factory Evento.fromJson(List<dynamic> json) {

2.然而,这可能会破坏其他东西。(为什么要将其定义为Map

var map1 = Map.fromIterable(response.body, key: (e) => e.name, value: (e) => e.value); 

(您可以在此处了解更多信息:https://bezkoder.com/dart-convert-list-map/)

我希望这是选项1!

 类似资料:
  • 我相信你知道上面的问题。我想知道我怎样才能解决它。我知道我的数据是列表形式的,但在我使用的数据类map中。我真的不明白我应该如何改变它的工作,基本上我只是跟随颤振。开发文档 如果你想知道我做了什么 我基本上是用json_serializable解析数据的。在使用测试数据进行的测试中,所有测试都运行良好。 我的数据: 我的模型包含一个标题,图像 ` 我正在使用以下代码使用数据: 我希望我写得清楚 -

  • out webserver将此结果返回为: 我用这个结构类来解析它 现在,当我从服务器成功获取数据时,我无法返回该数据,例如: 对于这行代码: 返回tring.map 我得到这个错误: 类型列表不是类型转换中的类型映射的子类型

  • 我的JSON有点像这样: 我的模型类: 这是我的api调用: 如何获取图像。小班?如果我需要澄清我的问题,请告诉我。我得到的错误列表不是Map类型的子类型

  • 我从github获取了代码,但仍然不起作用 生成FutureBuilder时引发了以下类型错误(脏,状态:_FutureBuilderState#a936c):类型“List”不是类型“Map”的子类型 在此列出声明 这是地图

  • 我试图从API获取数据。我得到了错误类型列表不是地图的子类型。我是新来的,不明白我在哪里犯了错误。 这是我的回帖功能: 在我的主屏幕中,我使用了一个,如下所示: 如何解决此错误?提前谢谢。

  • //我正在尝试此代码,但它没有添加到firebase //它给出了这些错误 处理手势时引发了以下_TypeError:类型“List”不是类型“String”的子类型 抛出异常时,这是堆栈:#0个SharedReferences。getString(包:共享首选项/共享首选项。dart:98:35)#1 CheckItemInNot(包:e_shop/Store/storehome.dart:33