Flutter Bloc读取LocalStorage报错:String非Map<String,dynamic>子类型
解决flutter_bloc读取LocalStorage时的类型转换错误
错误原因分析
这个错误本质是类型不匹配:你试图将读取到的String类型数据当作Map<String, dynamic>来使用,常见场景包括:
- 存储数据时未将对象序列化为JSON字符串,直接存了普通字符串或对象的
toString()结果 - 读取后直接将字符串赋值给了期望接收Map/模型类的变量,未做正确解析
- 调用
jsonDecode()时,传入的不是合法的JSON格式字符串
针对性解决方案
1. 修正数据存储逻辑
确保存储前将对象转为标准JSON字符串:
// 示例:存储用户数据 final userMap = {'id': 1, 'name': 'Meet'}; // 使用jsonEncode将Map转为JSON字符串后存储 await LocalStorage.instance.setString('user_info', jsonEncode(userMap));
避免以下错误存储方式:
// 错误:直接存储Map的toString()结果,读取后会得到类似"Instance of 'Map'"的字符串 await LocalStorage.instance.setString('user_info', userMap.toString());
2. 规范数据读取流程
读取后先验证数据格式,再解析为Map:
final storedStr = LocalStorage.instance.getString('user_info'); if (storedStr != null) { try { // 将JSON字符串解析为Map final userMap = jsonDecode(storedStr) as Map<String, dynamic>; // 转换为自定义模型类(如果有) final user = UserModel.fromJson(userMap); // 发送到Bloc更新状态 context.read<UserBloc>().add(LoadUserSuccess(user)); } catch (e) { // 解析失败时处理异常,比如打印日志或发送错误事件 print('解析JSON失败:$e'); context.read<UserBloc>().add(LoadUserFailed()); } }
3. 检查Bloc状态与事件的类型定义
确保Bloc的状态类中字段类型与数据匹配:
// 正确的状态类示例 class UserLoadedState extends Equatable { final UserModel user; // 类型为自定义模型类而非String const UserLoadedState(this.user); @override List<Object> get props => [user]; }
4. 调试定位问题
在读取数据后打印关键信息,快速定位问题点:
final storedData = LocalStorage.instance.getString('user_info'); print('存储数据类型:${storedData.runtimeType}'); print('存储数据内容:$storedData');
如果打印的内容不是{...}格式的JSON字符串,说明存储环节存在问题;如果是合法JSON但解析失败,检查模型类的fromJson方法是否正确。
内容的提问来源于stack exchange,提问作者Meet Bhanderi
相关产品推荐
相关产品推荐

