使用 Json 错误是 * type 'List<dynamic>' is not a subtype of type 'String'*

Posted

技术标签:

【中文标题】使用 Json 错误是 * type \'List<dynamic>\' is not a subtype of type \'String\'*【英文标题】:Working with Json Error is * type 'List<dynamic>' is not a subtype of type 'String'*使用 Json 错误是 * type 'List<dynamic>' is not a subtype of type 'String'* 【发布时间】:2020-04-12 18:28:43 【问题描述】:

这是我的回应 http://dummy.restapiexample.com/api/v1/employees

我正在显示来自 api 的列表,我在 response.body 中得到了完美的响应,但随后不知道发生了什么

我的 PODO 或模型是

class NewData 
  String id;
  String employeeName;
  String employeeSalary;
  String employeeAge;
  String profileImage;

  NewData(
      this.id,
        this.employeeName,
        this.employeeSalary,
        this.employeeAge,
        this.profileImage);

  factory NewData.fromJson(Map<String, dynamic> json) => NewData(
    id: json["id"],
    employeeName: json["employee_name"],
    employeeSalary: json["employee_salary"],
    employeeAge: json["employee_age"],
    profileImage: json["profile_image"],
  );


  Map<String, dynamic> toJson() 
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['employee_name'] = this.employeeName;
    data['employee_salary'] = this.employeeSalary;
    data['employee_age'] = this.employeeAge;
    data['profile_image'] = this.profileImage;
    return data;
  

我的 Main.dart 是

body: Container(
        child: Column(
          children: <Widget>[
            FutureBuilder<NewData>(
                future: fetchPost(),
                builder: (context, snapshot) 
                  if (snapshot.connectionState == ConnectionState.done) 
                    if (snapshot.hasError) 
                      return Text("ERROR : - " + snapshot.error.toString());
                    
                    List<NewData> data = snapshot.data as List<NewData>;
                    return new ListView.builder(
                      itemCount: data.length,
                      itemBuilder: (context, index) 
                        return new ListTile(
                          title: new Text(data[index].employeeName),
                        );
                      ,
                    );
                   else 
                    // By default, show a loading spinner.
                    return Center(
                      child: CircularProgressIndicator(),
                    );
                  
                ),
          ],
        ),
      ),
    );
  

  Future<NewData> fetchPost() async 
    var response = await http.get(url);
    if (response.statusCode == 200) 
      // If server returns an OK response, parse the JSON.
      var resp = json.decode(response.body);
      print(resp.toString());
      return NewData.fromJson(resp);
     else 
      // If that response was not OK, throw an error.
      throw Exception('Failed to load post');
    
  

但我得到了这个错误

类型“列表”不是类型“字符串”的子类型

帮我解决这个问题 我如何摆脱这个?

【问题讨论】:

我正在解释错误,您在分配为字符串时获取数组,即它的含义 这个错误本质上是告诉你你得到了一个列表,而 Flutter 需要一个字符串。您能否分享一个您正在解析的 JSON 示例? 【参考方案1】:

您需要进行一些更改才能使其正常工作:

    FutureBuilder&lt;NewData&gt;(FutureBuilder&lt;List&lt;NewData&gt;&gt;(

    List&lt;NewData&gt; data = snapshot.data as List&lt;NewData&gt;;List&lt;NewData&gt; data = snapshot.data;

    return new ListView.builder(return new Expanded(child: ListView.builder(

    fetchPost() method

完整代码:

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

class Demo extends StatefulWidget 
  @override
  _DemoState createState() => _DemoState();


class _DemoState extends State<Demo> 
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text("DEMO"),
      ),
      body: Container(
        child: Column(
          children: <Widget>[
            FutureBuilder<List<NewData>>(
                future: fetchPost(),
                builder: (context, snapshot) 
                  if (snapshot.connectionState == ConnectionState.done) 
                    if (snapshot.hasError) 
                      return Text("ERROR : - " + snapshot.error.toString());
                    

                    List<NewData> data = snapshot.data;

                    return new Expanded(
                        child: ListView.builder(
                      itemCount: data.length,
                      itemBuilder: (context, index) 
                        return new ListTile(
                          title: new Text(data[index].employeeName),
                        );
                      ,
                    ));
                   else 
                    // By default, show a loading spinner.
                    return Center(
                      child: CircularProgressIndicator(),
                    );
                  
                ),
          ],
        ),
      ),
    );
  

  Future<List<NewData>> fetchPost() async 
    var response =
        await http.get("http://dummy.restapiexample.com/api/v1/employees");
    if (response.statusCode == 200) 
      // If server returns an OK response, parse the JSON.
      var resp = json.decode(response.body);
      print(resp.toString());

      final parsed = resp.cast<Map<String, dynamic>>(); // added this
      return parsed
          .map<NewData>((json) => NewData.fromJson(json))
          .toList(); // add this too
     else 
      // If that response was not OK, throw an error.
      throw Exception('Failed to load post');
    
  


class NewData 
  String id;
  String employeeName;
  String employeeSalary;
  String employeeAge;
  String profileImage;

  NewData(
      this.id,
      this.employeeName,
      this.employeeSalary,
      this.employeeAge,
      this.profileImage);

  factory NewData.fromJson(Map<String, dynamic> json) => NewData(
        id: json["id"],
        employeeName: json["employee_name"],
        employeeSalary: json["employee_salary"],
        employeeAge: json["employee_age"],
        profileImage: json["profile_image"],
      );

  Map<String, dynamic> toJson() 
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['employee_name'] = this.employeeName;
    data['employee_salary'] = this.employeeSalary;
    data['employee_age'] = this.employeeAge;
    data['profile_image'] = this.profileImage;
    return data;
  

【讨论】:

感谢这项工作,并感谢您在完整代码中付出的额外努力。【参考方案2】:

您请求的 JSON 正在返回一个对象列表,并且在您的代码中您正在解析单个对象。因此,当您使用 NewData.fromJson(resp) 解析它时,您正在尝试解析对象列表而不是单个对象。

你最好这样做:

Iterable l = json.decode(rseponse.body);
List<NewData> dataList = l.map((Map model)=> NewData.fromJson(model)).toList();

来源:How to Deserialize a list of objects from json in flutter

然后,您将能够将fetchPost() 返回类型更新为Future&lt;List&lt;NewData&gt;&gt;

【讨论】:

以上是关于使用 Json 错误是 * type 'List<dynamic>' is not a subtype of type 'String'*的主要内容,如果未能解决你的问题,请参考以下文章

将 JSON 对象反序列化为 List<type> 不适用于 asmx 服务

使用 Json.NET 将异构 JSON 数组反序列化为协变 List<>

type argument cannot be of primitive type错误

SyntaxError: missing ] after element list 火狐问题

在使用“as JSON”呈现响应时更改 JSON 响应的 Content-Type

使用 json 数据获取错误和警告