Flutter使用Riverpod+Dartz时FutureProvider与Future<Either>类型不匹配问题问询
报错原因
你定义的activeCourseProvider泛型指定返回值类型为List<CourseModel>,但调用的activeCourses方法实际返回类型是Future<Either<ApiFailures, List<CourseModel>>>,二者类型不匹配触发编译错误。
原报错中文翻译:返回类型
Future<Either<ApiFailures, List<CourseModel>>>不符合闭包上下文要求的Future<List<CourseModel>>类型。
解决方案
根据你需要的错误处理方式,可选以下两种方案:
方案1:保留Dartz Either的函数式错误处理(推荐)
直接修改Provider的泛型声明,让Provider直接返回Either类型,你可以在UI层自主处理成功/失败分支,完整保留自定义ApiFailures的错误处理能力。
修改后的Provider代码如下:
final activeCourseProvider = FutureProvider.autoDispose.family<Either<ApiFailures, List<CourseModel>>, int>((ref, yearId) { final _courseRepository = ref.watch(coursesRepositoryProvider); return _courseRepository.activeCourses(yearId); });
UI层调用示例:
ref.watch(activeCourseProvider(传入的yearId)).when( loading: () => const CircularProgressIndicator(), error: (error, stackTrace) => Text('请求异常:$error'), data: (eitherData) => eitherData.fold( (failure) => Text(failure.map( noConnection: (_) => "当前无网络连接,请检查网络后重试", notFound: (_) => "未查询到对应课程信息", ).toString()), (courseList) => ListView.builder( itemCount: courseList.length, itemBuilder: (context, index) => CourseItem(data: courseList[index]), ), ), );
方案2:适配Riverpod原生错误处理逻辑
如果你不需要在UI层操作Either,也可以在Provider内部处理Either分支,将失败分支的ApiFailures作为异常抛出,直接复用Riverpod的AsyncError能力处理错误。
修改后的Provider代码如下:
final activeCourseProvider = FutureProvider.autoDispose.family<List<CourseModel>, int>((ref, yearId) async { final _courseRepository = ref.watch(coursesRepositoryProvider); final resultEither = await _courseRepository.activeCourses(yearId); return resultEither.fold( (failure) => throw failure, (courses) => courses, ); });
UI层可以直接在when的error回调中拿到抛出的ApiFailures对象,做对应的错误提示即可。
内容的提问来源于stack exchange,提问作者Fahmi Sawalha
相关产品推荐
相关产品推荐

