New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: Either as left and right #117
Comments
I think the more idiomatic solution to the SO question would use Future<Either<Failure, AuthUser>> call() async {
final userResponse = await _authRepository.getUser();
return userResponse.flatMap((user) {
final accessTokenExpiresAtMilliseconds =
user.accessTokenIssuedAtMilliseconds +
user.accessTokenExpiresInMilliseconds;
final accessTokenExpiresAtDateTime =
DateTime.fromMillisecondsSinceEpoch(accessTokenExpiresAtMilliseconds);
if (DateTime.now().isBefore(accessTokenExpiresAtDateTime)) {
return right(user);
}
return _authRepository.refreshUser(user: user);
});
} This makes some assumptions on the signatures of the |
The map is what I used before but you can get deeply nested by doing that if the logic is just a bit more complex. Other than that I don't think there is an async map either so it doesn't seem to work well with async functions. I understand that the either promotes handling all errors. But in certain situation I think you should be able to deviate from it so that the code doesn't become unnecessarily complex. |
For async behavior, I would recommend using |
Is there any example how to use combinators? I'm assuming this would work also for 2 eithers the have different types for right? How would one combine 2 eithers and fold it? |
Sure a simple example: final foo = right<String, int>(42);
final bar = right<String, String>("duck");
final combined = Either.map2(foo, bar, (a, b) => 'happy $a birthday $b!!');
final folded = combined.fold((l) => 'error: $l', (r) => r); |
Hi thanks for the example. I'm still however a bit confused. In my example I have 2 futures that I work with. The first one needs to resolve because I need it's result for the second one. Your example is not for async operations it seems. So you suggest using a Task right? I'm not seeing myself how a task would solve this problem. So the code below would work with the extension. But how can I make this same code work with the api provided by this package? A map won't work since we are working with a future here. Future<Either<Failure, SomeValue1>> doSomething1() {
// return left and right
}
Future<Either<Failure, SomeValue2>> doSomething2(SomeValue1 input) {
// return left and right
}
Future<Either<Failure, SomeValue2>> combine() {
final result = await doSomething1();
if(result.isLeft()){
return result.asLeft();
}
return doSomething2(result.asRight());
} |
Yes you're correct that in your case // Your original Future-based functions
Future<Either<Failure, SomeValue1>> doSomething1Fut() =>
throw UnimplementedError();
Future<Either<Failure, SomeValue2>> doSomething2Fut() =>
throw UnimplementedError();
// Dartz Task functions
Task<Either<Failure, SomeValue1>> doSomething1() =>
Task(() => doSomething1Fut());
Task<Either<Failure, SomeValue2>> doSomething2() =>
Task(() => doSomething2Fut());
// Using flatMap to sequence the Tasks, map2 to combine the Eithers
Task<Either<Failure, SomeValue3>> combine() {
return doSomething1().flatMap((value1) {
return doSomething2().map((value2) {
return Either.map2(value1, value2,
(a, b) => throw UnimplementedError('combine the values here'));
});
});
} |
For me a scenario like this comes up a lot. For example when you are working with remote and local datasources and you want to write to the cache or disk in-between. I can imagine that the solution I proposed doesn't align with the goals of this project. But I do think ideally there should be a more streamlined solution for this supported by the package itself. |
In the following scenario
https://stackoverflow.com/questions/75007868/with-dartz-is-it-possible-to-pass-a-failure-on-to-the-function-that-is-folding-m/75008089#75008089
it would be great to have an asLeft and asRight as was proposed in the answer.
Inside this, you may like to access data directly, this extension will help
The text was updated successfully, but these errors were encountered: