Flutter : isolate the right hand of Future<Either>

876 Views Asked by At

iam using riverpod with dartz , nad iam facing a problem that when using a future provider with my function i can't get my hand on the either as well , how can i isolate what i want to retrieve from the function with error handling !

my provider code :

final activeCourseProvider =
    FutureProvider.autoDispose.family<List<CourseModel>, int>((ref, yearId) {
  final _courseRepository = ref.watch(coursesRepositoryProvider);
  return _courseRepository.activeCourses(yearId);
});

my function code :

Future<Either<ApiFailures, List<CourseModel>>> activeCourses(int yearId) async {
   try{ final response = await http.post(
        Uri.parse("http://msc-mu.com/api_verfication.php"),
        body: {"flag": "selectcourses", "year": "$yearId"});
if (response.statusCode == 200) {
        var l = json.decode(response.body) as List<dynamic>;
        var courses = l.map((e) => CourseModel.fromJson(e)).toList();
        return right(courses);
      } else {
        return left(ApiFailures.notFound());
      }
    } on SocketException {
      return left(ApiFailures.noConnection());
    } on HttpException {
      return left(ApiFailures.notFound());
    }
  }

the error that pops up is : The return type 'Future<Either<ApiFailures, List<CourseModel>>>' isn't a 'Future<List<CourseModel>>', as required by the closure's context.

2

There are 2 best solutions below

1
On BEST ANSWER

It seems that your Provider activeCourseProvider is supposed to return a List<CourseModel>, not an Either<ApiFailures, List<CourseModel>>.

You could use fold the Either value as follows:

final activeCourseProvider = FutureProvider.autoDispose.family<List<CourseModel>, int>((ref, yearId) {
  final _courseRepository = ref.watch(coursesRepositoryProvider);
  return _courseRepository.fold<List<CourseModel>>(
    (ApiFailures failure) => {
      // Handle failure
      return [];
    },
    (List<CourseModel> r) => r
  );
});

However, you might also want to have your Provider returning an Either<ApiFailures, List<CourseModel>> value instead of a List<CourseModel>. That could be useful if you want to handle the ApiFailures further down in your presentation layer. This depends on your architecture.

0
On

This is because you declare the function will return a Either result:

Future<Either<ApiFailures, List<CourseModel>>>

but when you pass the Type:

FutureProvider.autoDispose.family<List<CourseModel>

the either is not handled, change this:

return _courseRepository.activeCourses(yearId);

to

final result= _courseRepository.activeCourses(yearId);
if(result.isRight()){
return result.gerOrElse(()=>null);
}else{
///handle left result
}