I try to create a repository with type safe parameters. For this, I created the function parameter as a typedef and use the Dartz package, to be able to return either a failure or the desired result.
The issue is, that I have to create a specific function, if I want to pass an argument of the typedef type.
typedef FailOrModel<T> = Future<Either<Failure, T>> Function();
class Repository {
Future<Either<Failure, T>> _runAfterSync<T>(FailOrModel func) async {
await synchronize().then(
(value) => value.fold(
(failure) {
log.e('Synchronization error: $failure');
},
(_) {},
),
);
return await func();
}
Future<Either<Failure, Storage>> getStorage(int id) async {
// Todo: Find out why lambda does not work
Future<Either<Failure, Storage>> func() async {
try {
final model = await localDataSource.getStorage(id);
return Right(model);
} on CacheException {
log.e('Could not load storage with id $id');
return Left(CacheFailure());
}
}
return await _runAfterSync<Storage>(func);
}
}
When I pass the identical function body as a lambda function directly, as I would like to, I get a runtime error:
Future<Either<Failure, Storage>> getStorage(int id) async {
return await _runAfterSync<Storage>(() async {
try {
final model = await localDataSource.getStorage(id);
return Right(model);
} on CacheException {
log.e('Could not load storage with id $id');
return Left(CacheFailure());
}
});
}
type 'Right<Failure, dynamic>' is not a subtype of type 'FutureOr<Either<Failure, Storage>>'
It is not a big deal, but maybe someone could enlighten me, how I am able to use a lambda function here, or why I get this error, if I use a lambda function.
The expected return type of
getStorage(int)
from a Future isEither<Failure, Storage>
. The mismatch occurs because you're trying to returnRight<Failure, dynamic>
.As what have been mentioned in the comments, you can pass
FailOrModel<T>
in_runAfterSync
to solve the issue.