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);
}