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

Flutter跨类传递TextField参数失败及JSON解析类型不匹配问题

Flutter输入框值传递与JSON解析错误问题

我创建了用于API请求的RemoteService类,尝试将MyCustomFormState中TextInput的文本值传递过去,但编译后无法获取输入框的值,同时出现JSON解析异常。


相关代码

RemoteService类

class RemoteService {
  
   Future<List<Member>?> getUser({String? textForm}) async {
    var clientuser = http.Client();
    var uriuser = Uri.parse('HTTP://MY URI//$textForm');
    var responseuse = await clientuser.get(uriuser);
    if (responseuse.statusCode == 200) {
      var json = responseuse.body;
      return memberFromJson(json);
    }
    return null; // 补充无返回值路径的默认返回
  }
}

MyCustomFormState类

class MyCustomFormState extends State<MyCustomForm> {
  List<Member>? user1;
  var isLoaded = false;
  TextEditingController textFieldValue = TextEditingController();

  @override
  void initState() {
    super.initState();
    // 移除此处的getUse调用,避免初始化时请求空参数API
    // getUse();
  }

  getUse() async {
    user1 = await RemoteService().getUser(textForm: textFieldValue.text);
    if (user1 != null) {
      setState(() {
        isLoaded = true;
      });
    }
  }
  
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Container(
          width: 200,
          child: TextFormField(
            controller: textFieldValue,
            decoration: InputDecoration(
              border: OutlineInputBorder(),
              fillColor: Color.fromARGB(255, 255, 255, 255),
              hintText: 'PLEASE ENTER ID',
            ), 
            // 无需额外onChanged回调,直接通过controller获取最新值
          ),
        ),
        Container(
          width: 120,
          height: 50,
          margin: EdgeInsets.only(top: 15),
          child: ElevatedButton(
            child: Text("LOGIN",style: TextStyle(
              fontSize: 16, fontWeight: FontWeight.bold),),
            style: ElevatedButton.styleFrom(
              primary: Color.fromARGB(255, 45, 160, 253),
              elevation: 0,
            ), 
            onPressed: () async {
              print("INPUT = ${textFieldValue.text}");
              await getUse(); // 点击按钮时才调用API获取数据
              print("Fetch API = ${user1?[0].name}");
            },
          ),
        ),
      ],
    );
  }
}

错误信息

Performing hot restart...                                               
Restarted application in 2,712ms.
E/flutter (13579): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type '(dynamic) => Member' is not a subtype of type '(String, dynamic) => MapEntry<dynamic, dynamic>' of 'transform'
E/flutter (13579): #0      memberFromJson (package:flutter_exit_interview/dtbmember.dart:8:79)
E/flutter (13579): #1      RemoteService.getUser (package:flutter_exit_interview/main.dart:1061:14)
E/flutter (13579): <asynchronous suspension>
E/flutter (13579): #2      MyCustomFormState.getUse (package:flutter_exit_interview/main.dart:83:13)
E/flutter (13579): <asynchronous suspension>
E/flutter (13579):

Member Model类

// To parse this JSON data, do
//
//     final member = memberFromJson(jsonString);

import 'package:meta/meta.dart';
import 'dart:convert';

List<Member> memberFromJson(String str) => List<Member>.from(json.decode(str).map((x) => Member.fromJson(x)));
String memberToJson(List<Member> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class Member {
    Member({
        required this.status,
        required this.personId,
        required this.code,
        required this.name,
        required this.nickname,
        required this.deptcode,
    });

    String status;
    String personId;
    String code;
    String name;
    String nickname;
    String deptcode;

    factory Member.fromJson(Map<String, dynamic> json) => Member(
        status: json["status"],
        personId: json["person_id"],
        code: json["code"],
        name: json["name"],
        nickname: json["nickname"],
        deptcode: json["deptcode"],
    );

    Map<String, dynamic> toJson() => {
        "status": status,
        "person_id": personId,
        "code": code,
        "name": name,
        "nickname": nickname,
        "deptcode": deptcode,
    };
}

问题分析与解决方案

1. JSON解析错误原因

错误提示type '(dynamic) => Member' is not a subtype of type '(String, dynamic) => MapEntry<dynamic, dynamic>',说明API返回的JSON结构和Model解析逻辑不匹配:

  • 当前memberFromJson假设返回的是数组格式,但实际API可能返回单个对象,或嵌套了数组的复合对象(比如{"data": [...], "code": 200})。

对应解决方式:

  • 如果API返回单个Member对象:
    修改memberFromJson方法:

    Member memberFromJson(String str) => Member.fromJson(json.decode(str));
    

    同时调整RemoteService的返回类型:

    Future<Member?> getUser({String? textForm}) async {
      // 其他代码不变
      return memberFromJson(json);
    }
    

    并在MyCustomFormState中修改user1类型为Member? user1;,打印语句改为print("Fetch API = ${user1?.name}");

  • 如果API返回嵌套数组的复合对象:
    修改memberFromJson方法,指定解析数组的路径:

    List<Member> memberFromJson(String str) => List<Member>.from(json.decode(str)["data"].map((x) => Member.fromJson(x)));
    

2. 输入框值传递问题

原代码在initState中调用getUse(),此时输入框为空,导致请求空参数API;点击按钮时未重新触发API请求,所以user1始终是初始空值。

对应解决方式:

  • 移除initState中的getUse()调用;
  • 在登录按钮的onPressed中异步调用getUse(),确保使用输入框的最新值请求API;
  • 直接通过textFieldValue.text获取输入值,无需额外维护getusevalue变量和onChanged回调。

内容的提问来源于stack exchange,提问作者Rasale Migle

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 04:04:53