You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter调用自定义Node Express API出现TypeError问题求助

问题描述

我是Flutter新手,跟着教程学习时,用http库调用自己用Node Express搭建的API遇到了TypeError:TypeError (type '(dynamic) => User' is not a subtype of type '(String, dynamic) => MapEntry<dynamic, dynamic>' of 'transform'),但调用jsonplaceholder的模拟API却能正常运行,这是为什么?


附相关代码

User模型代码

import 'dart:convert';

List<User> userFromJson(String str) =>
    List<User>.from(json.decode(str).map((x) => User.fromJson(x)));

String userToJson(List<User> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class User {
  int index;
  int id;
  String firstName;
  String lastName;
  String phone;
  String email;

  User({
    required this.index,
    required this.id,
    required this.firstName,
    required this.lastName,
    required this.phone,
    required this.email,
  });

  factory User.fromJson(Map<String, dynamic> json) => User(
        index: json["index"],
        id: json["id"],
        firstName: json["first_name"],
        lastName: json["last_name"],
        phone: json["phone"],
        email: json["email"],
      );

  Map<String, dynamic> toJson() => {
        "index": index,
        "id": id,
        "first_name": firstName,
        "last_name": lastName,
        "phone": phone,
        "email": email,
      };
}

HTTP GET请求代码

import 'package:http/http.dart' as http;

const String baseUrl = "http://192.168.166.153:5000/api/user";

class BaseClient {
  var client = http.Client();
  Future<dynamic> get(String api) async {
    var url = Uri.parse(baseUrl + api);
    var headers = {
      "autherization":
          "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InNzZ2dAbW0uaW4iLCJpYXQiOjE2ODQ2NzEwMDEsImV4cCI6MTY4NDcyNTAwMX0.lTIIgHi7129dxvoI83sN82r5sHG88E8RGL2nsEimD1I",
    };

    var response = await client.get(url, headers: headers);
    if (response.statusCode == 200) {
      return response.body;
    } else {
      // else part
    }
  }
}

API返回数据

{
    "responseCode": 200,
    "responseMessage": "Everything worked as expected",
    "responseData": [
        {
            "index": 2,
            "id": 1,
            "first_name": "oggy",
            "last_name": "ss",
            "phone": "1234567890",
            "email": "ss@ss.in"
        },
        {
            "index": 3,
            "id": 2,
            "first_name": "olly",
            "last_name": "ss",
            "phone": "1234567899",
            "email": "gg@gg.in"
        },
        {
            "index": 4,
            "id": 3,
            "first_name": "jack",
            "last_name": "jj",
            "phone": "1234567898",
            "email": "jj@jj.in"
        }
    ]
}

问题原因

你的userFromJson方法是直接把整个JSON字符串解析成数组后转User对象,但自己的API返回的不是直接的用户数组,而是一个包含responseData字段的外层对象,用户数组嵌套在responseData里。而jsonplaceholder的API返回的是直接的用户数组,所以之前的代码能正常运行。

错误提示的本质是:你把Map类型的外层对象传给了期望处理数组的map方法,导致类型不匹配。


解决方案

1. 修改User模型的解析方法

调整userFromJson,先解析出外层Map,再取responseData字段对应的数组转换:

List<User> userFromJson(String str) {
  final jsonData = json.decode(str);
  return List<User>.from(jsonData["responseData"].map((x) => User.fromJson(x)));
}

2. 优化BaseClient的返回值(可选)

建议在get方法里直接返回解析后的JSON对象,避免重复解析字符串:

Future<dynamic> get(String api) async {
  var url = Uri.parse(baseUrl + api);
  var headers = {
    "autherization":
        "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InNzZ2dAbW0uaW4iLCJpYXQiOjE2ODQ2NzEwMDEsImV4cCI6MTY4NDcyNTAwMX0.lTIIgHi7129dxvoI83sN82r5sHG88E8RGL2nsEimD1I",
  };

  var response = await client.get(url, headers: headers);
  if (response.statusCode == 200) {
    return json.decode(response.body); // 直接返回解析后的JSON对象
  } else {
    // 添加错误处理,比如抛出异常
    throw Exception('请求失败,状态码:${response.statusCode}');
  }
}

调用示例:

final client = BaseClient();
final response = await client.get('/your-endpoint');
final users = List<User>.from(response["responseData"].map((x) => User.fromJson(x)));

内容的提问来源于stack exchange,提问作者sumanth.js

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 05:43:19