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

Flutter获取数据触发NoSuchMethodError:方法'[]'被调用在null上

问题排查:Flutter中NoSuchMethodError异常(调用null的[]方法)

异常详情

======== Exception caught by widgets library =======================================================

The following NoSuchMethodError was thrown building ProfileScreen(dirty, state: _ProfileScreenState#189a3):
The method '[]' was called on null.
Receiver: null
Tried calling: []("firstname")

相关代码

class EditProfile extends Stateful Widget {
  const EditProfile({Key? key}) : super(key: key);

  @override
  _EditProfileState createState() => _EditProfileState();
}

class _EditProfileState extends State<EditProfile> {
  bool isApiCallProcess = false;
  bool hidePassword = true;
  var _loadedProducts;
  late SharedPreferences _sharedPreferences;
  static final GlobalKey<FormState> globalFormKey = GlobalKey<FormState>();
  final TextEditingController _firstnameController = TextEditingController();
  final TextEditingController _lastnameController = TextEditingController();
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _mobileController = TextEditingController();
  final TextEditingController _addressController = TextEditingController();

  final validator1 = ValidationBuilder().email().maxLength(50).build();

  String? firtname;
  String? lastname;
  String? email;
  String? mobile;
  String? address;

  @override
  void initState() {
    super.initState();
    _fetchData();
  }

  Future<void> _fetchData() async {
    var _sharedPreferences = await SharedPreferences.getInstance();
    var userid = _sharedPreferences.getInt('userid');
    if (userid != null) {
      userid = userid;
    } else {
      userid = 1;
    }

    print(userid.toString() + 'hello');

    final response = await http.post(
        Uri.parse('${Utils.baseUrl}/profile/getData'),
        headers: {"Accept": "Application/json"},
        body: {'user_id': userid.toString()});
    if (response.statusCode == 200) {
      var decodedData = jsonDecode(response.body);
      print(decodedData);
    }
    else{
      throw Exception('Failed to load..');
    }

    var f_data = json.decode(response.body);

    print(f_data);
    setState(() {
      _loadedProducts = f_data["data"][0];
    });
  }
}

问题原因及修复方案

核心原因

异常本质是UI渲染时_loadedProducts为null,直接调用_loadedProducts["firstname"]触发报错。具体诱因:

  1. _fetchData是异步方法,UI会优先完成初始化渲染,此时_loadedProducts未被赋值,处于null状态
  2. 接口返回的f_data["data"]可能不存在、不是数组,或者数组为空,导致f_data["data"][0]返回null
  3. 接口请求异常时直接抛出错误,未更新_loadedProducts状态,导致其一直为null

修复步骤

1. 初始化_loadedProducts为默认值

避免初始状态为null,改为空Map:

var _loadedProducts = {};

2. 渲染前判断数据状态,显示加载提示

在build方法中先检查数据是否就绪,未就绪时显示加载状态:

@override
Widget build(BuildContext context) {
  if (_loadedProducts.isEmpty) {
    return const Center(child: CircularProgressIndicator());
  }
  // 原有UI渲染逻辑
  return ...;
}

3. 安全处理接口返回数据

确保data字段存在且有效后再赋值:

setState(() {
  // 多层判断避免空指针
  if (f_data.containsKey("data") && 
      f_data["data"] is List && 
      f_data["data"].length > 0) {
    _loadedProducts = f_data["data"][0];
  } else {
    _loadedProducts = {};
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(content: Text("暂无用户数据"))
    );
  }
});

4. 取值时添加空安全防护

即使做了前置判断,取值时仍建议用空安全运算符:

// 替代直接_loadedProducts["firstname"]
_loadedProducts?["firstname"] ?? ""

5. 完善异常捕获与状态更新

在异步请求中包裹try-catch,确保异常场景下_loadedProducts能被正确更新:

Future<void> _fetchData() async {
  try {
    var _sharedPreferences = await SharedPreferences.getInstance();
    // 简化空判断逻辑
    var userid = _sharedPreferences.getInt('userid') ?? 1;

    final response = await http.post(
        Uri.parse('${Utils.baseUrl}/profile/getData'),
        headers: {"Accept": "Application/json"},
        body: {'user_id': userid.toString()});
    
    if (response.statusCode == 200) {
      var f_data = json.decode(response.body);
      setState(() {
        if (f_data.containsKey("data") && 
            f_data["data"] is List && 
            f_data["data"].length > 0) {
          _loadedProducts = f_data["data"][0];
        } else {
          _loadedProducts = {};
        }
      });
    } else {
      setState(() => _loadedProducts = {});
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text("加载失败:${response.statusCode}"))
      );
    }
  } catch (e) {
    setState(() => _loadedProducts = {});
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text("请求异常:$e"))
    );
  }
}

内容的提问来源于stack exchange,提问作者Charudatt Palvi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 18:17:40