【问题标题】:How to map dynamic json api responses in dart如何在 dart 中映射动态 json api 响应
【发布时间】:2021-11-24 19:53:52
【问题描述】:

我有一个 API 响应负载,正文中有动态数据。 API 返回data 标记中的对象列表。我试图在运行时将响应映射到适当的模型,但是,这样做时会收到一条错误消息。如何在运行时映射动态响应对象而不为每个对象显式创建 API 响应模型?理想情况下,解决方案应该能够确定响应对象在运行时应该映射到的目标模型。

我的代码出现以下错误:The argument type 'List<Map<String, dynamic>>' can't be assigned to the parameter type 'Map<String, dynamic>'.

按照我的尝试:

return ApiResponse<Team>.fromJson(json.decode(response.body), (data) => Team.fromJson(data) as List<Map<String, dynamic>>);
// Maps the API response to object
class ApiResponse<T> {
  int status;
  String? message;
  T data;

  ApiResponse({
    required this.status,
    this.message,
    required this.data,
  });

  factory ApiResponse.fromJson(Map<String, dynamic> json, Function(List<Map<String, dynamic>>) create) {
    return ApiResponse<T>(
      status: json['status'],
      message: json['message'],
      data: create(json['data']),
    );
  }
}

我的模型


class User{
  int? id;
  String? name;
  String? description;
  DateTime? createdAt;
  DateTime? updatedAt;

  User({
    this.id,
    this.name,
    this.description,
    this.createdAt,
    this.updatedAt
  });

  factory User.fromJson(Map<String, dynamic> json){
    return User(
      id: json['id'],
      name: json['name'],
      description: json['description'],
      createdAt: DateTime.parse(json['created_at']),
      updatedAt: DateTime.parse(json['updated_at']),
    );
  }
}


class Team {
  int id;
  String? name;
  String? region;
  DateTime? createdAt;
  DateTime? updatedAt;

  Team({
    required this.id,
    this.name,
    this.region,
    this.createdAt,
    this.updatedAt,
  });

  factory Team.fromJson(Map<String, dynamic> json){
    return Team(
      id: json['id'],
      name: json['name'],
      region: json['region'],
      createdAt: DateTime.parse(json['created_at']),
      updatedAt: DateTime.parse(json['updated_at']),
    );
  }
}

API 响应


{
  "status": 200,
  "message": "Returned",
  "data": [
    {
      "id": 1,
      "name": "Trevo Mgino",
      "description": "A Description",
      "created_at": "2021-09-29T06:47:03.000000Z",
      "updated_at": "2021-09-29T06:47:03.000000Z"
    }
  ],
}
{
  "status": 200,
  "message": "Activated",
  "data": [
    {
      "id": 1,
      "name": "Team A",
      "region": "Region 1",
      "created_at": "2021-09-29T06:47:03.000000Z",
      "updated_at": "2021-09-29T06:47:03.000000Z"
    },
    {
      "id": 2,
      "name": "Team B",
      "region": "Region 1",
      "created_at": "2021-09-29T06:47:03.000000Z",
      "updated_at": "2021-09-29T06:47:03.000000Z"
    }
  ],
}

【问题讨论】:

  • 只需解码您的 json 并传递此 json team.formjson(json)

标签: json flutter dart


【解决方案1】:

Team.fromJsonMap&lt;String, dynamic&gt; 作为参数,但你给它一个List&lt;Map&lt;String, dynamic&gt;&gt;

我认为你想要的是改变你给的第一个表达式:

ApiResponse<Team>.fromJson(
  json.decode(response.body),
  (data) => data.map((teamJson) => Team.fromJson(teamJson)),
)

您还可以键入工厂正在使用的安全类型:

class ApiResponse<T> {
  int status;
  String? message;
  T data;

  ApiResponse({
    required this.status,
    this.message,
    required this.data,
  });

  factory ApiResponse.fromJson(
    Map<String, dynamic> json,
    T Function(List<Map<String, dynamic>>) create,
  ) {
    return ApiResponse<T>(
      status: json['status'],
      message: json['message'],
      data: create(json['data']),
    );
  }
}

如果这样做,您还必须再次更改第一个表达式以编写正确的类型(我认为您犯了错误,但也许我错了):

ApiResponse<List<Team>>.fromJson(
  json.decode(response.body),
  (data) => data.map((teamJson) => Team.fromJson(teamJson)).toList(),
);

【讨论】:

    【解决方案2】:

    所以我设法用以下代码解决了问题:

    // Maps the API response to object
    class ApiResponse<T> {
      int status;
      String? message;
      T data;
    
      ApiResponse({
        required this.status,
        this.message,
        required this.data,
      });
    
      factory ApiResponse.fromJson(Map<String, dynamic> json, List<T> Function(List<dynamic>) create) {
        return ApiResponse<T>(
          status: json['status'],
          message: json['message'],
          data: create(json['data']),
        );
      }
    }
    

    调用映射器

    return ApiResponse<Team>.fromJson(json.decode(response.body),
          (data) => data.map((tData) => Team.fromJson(tData)).toList());
    

    【讨论】:

      猜你喜欢
      • 2021-08-25
      • 1970-01-01
      • 2022-12-29
      • 1970-01-01
      • 2017-12-04
      • 2021-06-17
      • 2018-05-05
      • 2019-06-23
      • 2019-11-07
      相关资源
      最近更新 更多