Flutter News Toolkit获取分类时类型转换错误求助
解决
type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>'类型转换错误 问题根源
你的分类接口(WordPress的/wp-json/wp/v2/categories)返回的JSON是数组(List),但你在两处代码中都强行将其转换为Map<String, dynamic>,这直接触发了类型不匹配错误。
分步修复方案
1. 重构HTTP响应扩展方法,适配多格式返回
原扩展方法固定返回Map,无法兼容返回数组的接口。修改为返回dynamic,让每个接口方法自行处理对应格式:
extension on http.Response { dynamic json() { try { final decodedBody = utf8.decode(bodyBytes); log("MyLog $decodedBody"); return jsonDecode(decodedBody); } catch (error, stackTrace) { Error.throwWithStackTrace( BernardinaiApiMalformedResponse(error: error), stackTrace, ); } } }
2. 调整CategoriesResponse的JSON解析逻辑
让CategoriesResponse同时支持从数组或对象解析,兼容接口返回格式:
class CategoriesResponse { final List<CategoriesInfo> categories; CategoriesResponse({required this.categories}); factory CategoriesResponse.fromJson(dynamic json) { // 处理接口直接返回数组的情况(如WordPress分类接口) if (json is List) { return CategoriesResponse( categories: json .map((item) => CategoriesInfo.fromJson(item as Map<String, dynamic>)) .toList(), ); } // 处理包含categories字段的对象格式(兼容其他接口) else if (json is Map<String, dynamic>) { return CategoriesResponse( categories: (json['categories'] as List) .map((item) => CategoriesInfo.fromJson(item as Map<String, dynamic>)) .toList(), ); } else { throw ArgumentError('Invalid JSON format for CategoriesResponse'); } } }
3. 修复NewsDataSource中的getCategories方法
WordPress分类接口返回的是分类对象数组,不是包含categories字段的对象,且每个分类是Map结构而非字符串,需修正解析逻辑:
Future<List<Category>> getCategories() async { final uri = Uri.parse('https://www.mynewsurl.com/wp-json/wp/v2/categories'); final categoriesResponse = await http.get(uri); if (categoriesResponse.statusCode == HttpStatus.ok) { // 直接解析为List<dynamic> final List<dynamic> categoriesList = jsonDecode(categoriesResponse.body) as List<dynamic>; log("MyLog categoriesList: $categoriesList"); // 从分类对象中提取slug字段,转换为Category枚举 final List<Category> categories = categoriesList.map((dynamic categoryData) { final String categorySlug = (categoryData as Map<String, dynamic>)['slug'] as String; log("MyLog categorySlug: $categorySlug"); return Category.fromString(categorySlug); }).toList(); log("MyLog categories to return: $categories"); return categories; } else { // 错误处理兼容多种返回格式 final dynamic errorBody = jsonDecode(categoriesResponse.body); throw BernardinaiApiRequestFailure( statusCode: categoriesResponse.statusCode, body: errorBody is Map<String, dynamic> ? errorBody : {}, ); } }
关键说明
- 不要强行统一所有接口的返回格式:不同接口可能返回数组或对象,扩展方法需保持灵活性
- 必须匹配接口实际返回结构:WordPress分类接口直接返回分类对象数组,无需读取
categories字段 - 枚举转换需基于接口返回的实际字段:分类对象包含
slug/name等字段,无法直接转换为字符串
内容的提问来源于stack exchange,提问作者T1D
相关产品推荐
相关产品推荐

