首次进入注册页时可选参数为空引发NoSuchMethodError问题
问题描述
我在Dart中定义了如下结构的对象:
{ name: , lastname: , phone: , email: }
并通过以下代码在Flutter的RegistrationPage中打印该对象:
class RegistrationPage extends StatefulWidget { // 接收从第一页传递过来的数据用于注册 final info; const RegistrationPage({this.info,Key? key}) : super(key: key); @override State<RegistrationPage> createState() => _RegistrationPage(); } class _RegistrationPage extends State<RegistrationPage> { @override void initState() { super.initState(); logUserInfo(); } void logUserInfo() { var userFilling = widget.info; log("$userFilling"); } }
用户完成注册页填写后需继续填写其他页面才可完成注册,同时支持返回上一页。当用户返回注册页时,我希望通过widget.info填充之前填写的内容(示例如下)以支持编辑:
{ name: "firstname", lastname: "lastname" , phone: +99999, email: "email@email.com"}
首次进入注册页时,该可选对象为空。
但当我尝试通过以下代码为文本控制器赋值时:
myController.text = (widget.info['email'] != null)?widget.info['email']:"",;
出现错误:
NoSuchMethodError: The method '[]' was called on null. Receiver: null. Tried calling [](email)
请问如何实现:若参数对象为空则保持文本控制器为空,若不为空则填充对应内容,同时避免上述空指针错误?
解决方案
错误根源是首次进入页面时widget.info本身为null,直接调用widget.info['email']等于在null上执行索引操作,触发空指针异常。以下是几种可行的解决方式:
方法1:利用空安全运算符简化判断
使用Dart的可选链运算符(?.)和空合并运算符(??),先判断widget.info是否非空,再读取字段:
myController.text = widget.info?['email'] ?? "";
widget.info?['email']:如果widget.info不为null,读取email字段;若为null,整个表达式返回null?? "":若前面的结果为null,就用空字符串替代
方法2:给info设置默认空Map
在RegistrationPage的构造函数中,给info设置默认值为空Map,确保widget.info永远不会是null:
class RegistrationPage extends StatefulWidget { // 明确指定类型为Map,提升类型安全性 final Map<String, dynamic> info; // 设置默认值为空不可变Map const RegistrationPage({this.info = const {}, Key? key}) : super(key: key); @override State<RegistrationPage> createState() => _RegistrationPage(); }
之后赋值时无需再判断info是否为null,直接写:
myController.text = widget.info['email'] ?? "";
方法3:使用类型安全的模型类(推荐)
如果项目规模较大,建议定义专用的用户信息模型类,替代原始Map,既避免类型错误,又能更优雅处理空值:
class UserInfo { final String? name; final String? lastName; final String? phone; final String? email; const UserInfo({this.name, this.lastName, this.phone, this.email}); // 从Map转换为模型类的工厂方法 factory UserInfo.fromMap(Map<String, dynamic>? map) { if (map == null) { return const UserInfo(); } return UserInfo( name: map['name'], lastName: map['lastname'], phone: map['phone'], email: map['email'], ); } }
修改RegistrationPage的参数类型:
class RegistrationPage extends StatefulWidget { final UserInfo info; // 默认创建空的UserInfo对象 const RegistrationPage({this.info = const UserInfo(), Key? key}) : super(key: key); @override State<RegistrationPage> createState() => _RegistrationPage(); }
赋值时直接调用模型类属性:
myController.text = widget.info.email ?? "";
这种方式代码可读性更高,维护成本更低,适合中大型项目。
内容的提问来源于stack exchange,提问作者umarkaa
相关产品推荐
相关产品推荐

