错误颤振:List<dynamic> 不是 Map<String, dynamic> 类型的子类型

Posted

技术标签:

【中文标题】错误颤振:List<dynamic> 不是 Map<String, dynamic> 类型的子类型【英文标题】:Error Flutter: List<dynamic> is not a subtype of type Map<String, dynamic> 【发布时间】:2021-11-20 15:03:49 【问题描述】:

谁能帮我解决这个问题。

我目前正在构建一个从 mysql 读取数据的应用程序。 我无法使用颤振 http 请求从 json 获取数据,因为它得到了这个错误:列表不是 Map 类型的子类型 谁能帮帮我。

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:http/http.dart' show get;
import 'dart:convert';

void main() => runApp(
    MyApp(
        txtscr: obtenirTxtscr()
    )
);
class Txtscr 
  final String id;
  final String content;
  Txtscr(
    required this.id,
    required this.content,
  );

  factory Txtscr.fromJson(Map<String, dynamic> jsonData) 
    return Txtscr(
      id: jsonData['id'],
      content: jsonData['content'],
    );
  

Future<Txtscr> obtenirTxtscr() async 
final jsonEndpoint = Uri.parse('https://www.domaine.com/txtscr.php');
final response = await get(jsonEndpoint);
if(response.statusCode == 200) 
return Txtscr.fromJson(json.decode(response.body));
  else 
  throw Exception("Error al obtenir el JSON");
class MyApp extends StatelessWidget 
final Future<Txtscr> txtscr;

  MyApp(Key? key, required this.txtscr): super(key: key);

  @override
  Widget build(BuildContext context) 
    // TODO: implement build
    return MaterialApp(
      title: "JSON URL",
      theme: ThemeData(
        primarySwatch: Colors.red,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text("Text Json"),
        ),
        body: Center(
          child: FutureBuilder<Txtscr>(
            future: txtscr,
            builder: (context, snapshot) 
              if(snapshot.hasData) 
                return Text(
                    "ID: " + snapshot.data!.id + "\n" +
                    "Content: " + snapshot.data!.content
                );
               else if(snapshot.hasError) 
                return Text("$snapshot.error");
              
              return CircularProgressIndicator();
            ,
          ),),),
    );
  

如何纠正这个错误?

【问题讨论】:

你能贴出 print(response.body) 在 obtenirTxtscr() 函数中给出的内容吗? 这是 JSON 文件的一部分:[ "id": "62", "content": "Saison de spectacles" ] 【参考方案1】:

您的 JSON 结果是一个数组(列表),而不是您的这部分代码所期望的映射:Txtscr.fromJson(json.decode(response.body))。您可以通过以下步骤解决它:

    将您的结果解释为ListTxtscr 对象。像这样重构你的未来:
Future<List<Txtscr>> obtenirTxtscr() async       // <-- added List
  final jsonEndpoint = Uri.parse('https://www.domaine.com/txtscr.php');
  final response = await get(jsonEndpoint);
  if (response.statusCode == 200) 
      return (json.decode(response.body) as List) // <-- added mapping
          .map((entry) => Txtscr.fromJson(entry))
          .toList();
   else 
    throw Exception("Error al obtenir el JSON");
  


    同时更改 MyApp 中的未来声明:
class MyApp extends StatelessWidget 
 Future<List<Txtscr>> txtscr;
    现在您将在FutureBuilder 中获得一个数组(列表)。如果列表中有 1 项或更多项,您必须决定要做什么。
FutureBuilder<Txtscr>(
  future: txtscr,
  builder: (context, snapshot) 
    if(snapshot.hasData) 
      // here you will have snapshot.data! as a list
      // so you can use the below code for first element
      // but it could have 0 or more items, you have to handle it
      return Text(
          "ID: " + snapshot.data![0].id + "\n" +
          "Content: " + snapshot.data[0]!.content
      );
     else if(snapshot.hasError) 
      return Text("$snapshot.error");
    
    return CircularProgressIndicator();
  ,
)

【讨论】:

【参考方案2】:

只需更改此行

return Txtscr.fromJson(json.decode(response.body));

return Txtscr.fromJson(json.decode(response.body)[0]);

注意:数组 JSON 不是有效的 Map,这就是您收到错误的原因。

【讨论】:

以上是关于错误颤振:List<dynamic> 不是 Map<String, dynamic> 类型的子类型的主要内容,如果未能解决你的问题,请参考以下文章

颤振错误:预期类型为“FutureOr<List<dynamic>>”的值,但得到类型为“_JsonMap”的值之一

如何使用 StreamBuilder 消除颤振数据表错误“预期类型为 'List<DataRow>',但得到类型为 'List<dynamic>”的值之一?

颤振错误:参数类型“列表<动态>?”不能分配给参数类型“列表<动态>”

类型“List<dynamic>”不是“Map<String”类型的子类型,在颤振应用中是动态的

未处理的异常:类型 'List<dynamic>' 不是颤振中类型 'Map<dynamic, dynamic>' 的子类型

颤振无法分配参数类型'List<dynamic>'