Home > database >  Riverpod : future provider is stuck on loading
Riverpod : future provider is stuck on loading

Time:11-09

Describe the bug when executing the provider with ref.read or ref.watch the result is the same , it is stuck on the loading block , while testing the api in postman works fine , the funny thing is that the api call gets executed and whenever i print something inside it it appears in the console

To Reproduce in presentation layer

onpressed:()=>ref
                                                  .read(getPatientProvider(
                                                      r.api_token))
                                                  .when(data: (data) {
                                                data.fold(
                                                    (l) => print(
                                                        "something wrong happened"),
                                                    (r) async {
                                                  print(r.id);
                                                  print("hello");
                                                  patient.value = patient.value
                                                      .copyWith(
                                                          name: r.name,
                                                          aliid: r.id,
                                                          appointments: r
                                                              .patient_appointments,
                                                          fcmtoken: token);
                                                  ref.read(docexist(r.id)).when(
                                                      loading: () =>
                                                          print("loading"),
                                                      error: (error, _) =>
                                                          print(error),
                                                      data: (data) async {
                                                        print("heloo");
                                                        if (data.isEmpty) {
                                                          print(
                                                              "data is not empty");
                                                        } else {
                                                          return print(
                                                              "logged in normally");
                                                        }
                                                      });
                                                });
                                              }, error: (error, _) {
                                                print(error);
                                              }, loading: () {
                                                print("object");
                                              })

Provider with riverpod generator

@riverpod
Future<Either<ApiFailures, dynamic>> getPatient(
    GetPatientRef ref, String token) async {
  final patientProvider = ref.watch(patientRepositoryProvider);
  return patientProvider.getInfo(token);
}

infrastructure layer

@override
  Future<Either<ApiFailures, dynamic>> getInfo(String token) {
    var dio = Dio();
    final result = TaskEither<ApiFailures, PatientModel>(() async {
      try {
        final response = await dio.get(
            "https://xxxxxxxx/GetInfo?api_token=$token");
        if (response.data == null) {
          return const Left(ApiFailures.notfound());
        } else {
          PatientModel patientModel =
              PatientModel.fromJson(response.data["User"]);
          return Right(patientModel);
        }
      } catch (err, st) {
        final message = 'error ${err.runtimeType}]';

        if (kDebugMode) log(message, error: err, stackTrace: st);

        if (err is DioError) {
          return Left(ApiFailures.fromDioError(error: err));
        }
        return const Left(ApiFailures.internalError());
      }
    });
    return result.map((r) => r).run();
  }

Expected behavior it should get the data as always

CodePudding user response:

Calling "when" inside a click handler such as onPressed as you did does not make sense.

"when" does not wait for the future to complete. It executes immediately based on the current status of the future.
Considering that when you call it, you just triggered the future, then the future at that time will always be in loading state.

What you want is something like async/await, where you can wait until the completion of your future.

You could do that with:

onPressed: () async {
  final value = await ref.read(provider.future);
}
  • Related