I am looking to extract a value easily from a method that return a type Either<Exception, Object>
.
I am doing some tests but unable to test easily the return of my methods.
For example:
final Either<ServerException, TokenModel> result = await repository.getToken(...);
To test I am able to do that
expect(result, equals(Right(tokenModelExpected))); // => OK
Now how can I retrieve the result directly?
final TokenModel modelRetrieved = Left(result); ==> Not working..
I found that I have to cast like that:
final TokenModel modelRetrieved = (result as Left).value; ==> But I have some linter complain, that telling me that I shouldn't do as to cast on object...
Also I would like to test the exception but it's not working, for example:
expect(result, equals(Left(ServerException()))); // => KO
So I tried this
expect(Left(ServerException()), equals(Left(ServerException()))); // => KO as well, because it says that the instances are different.
Ok here the solutions of my problems:
To extract/retrieve the data
final Either<ServerException, TokenModel> result = await repository.getToken(...);
result.fold(
(exception) => DoWhatYouWantWithException,
(tokenModel) => DoWhatYouWantWithModel
);
//Other way to 'extract' the data
if (result.isRight()) {
final TokenModel tokenModel = result.getOrElse(null);
}
To test the exception
//You can extract it from below, or test it directly with the type
expect(() => result, throwsA(isInstanceOf<ServerException>()));
Another way to extract the value is simply to convert to Option
, then to a dart
nullable:
final Either<Exception, String> myEither = Right("value");
final String? myValue = myEither.toOption().toNullable();
If you like you can define a simple extension to shortcut this:
extension EitherHelpers<L, R> on Either<L, R> {
R? unwrapRight() {
return toOption().toNullable();
}
}
I can't post a comment... But maybe you could look at this post . It's not the same language, but looks like it's the same behaviour.
Good luck.
Friends,
just create dartz_x.dart like this one.
import 'package:dartz/dartz.dart';
extension EitherX<L, R> on Either<L, R> {
R asRight() => (this as Right).value; //
L asLeft() => (this as Left).value;
}
And use like that.
import 'dartz_x.dart';
void foo(Either<Error, String> either) {
if (either.isLeft()) {
final Error error = either.asLeft();
// some code
} else {
final String text = either.asRight();
// some code
}
}
Future<Either<Failure, FactsBase>> call(Params params) async {
final resulting = await repository.facts();
return resulting.fold(
(failure) {
return Left(failure);
},
(factsbase) {
DateTime cfend = sl<EndDateSetting>().finish;
List<CashAction> actions = factsbase.transfers.process(facts: factsbase, startDate: repository.today, finishDate: cfend); // process all the transfers in one line using extensions
actions.addAll(factsbase.transactions.process(facts: factsbase, startDate: repository.today, finishDate: cfend));
for(var action in actions) action.account.cashActions.add(action); // copy all the CashActions to the Account.
for(var account in factsbase.accounts) account.process(start: repository.today);
return Right(factsbase);
},
);
}
extension EitherExtension<L, R> on Either<L, R> {
R? getRight() => fold<R?>((_) => null, (r) => r);
L? getLeft() => fold<L?>((l) => l, (_) => null);
}
I return fold result on Either type
@override
Future<Either<Failure, bool>> call(UpdateReceiptParams params) async {
Either<Failure, ProcurementStore> procurementStore =
await _getProcurementStore();
return procurementStore.fold((_) => Left(ServerFailure()),
(procurementlStore) async {
List<ReceiptItem> receiptItems =
_getReceiptItem(params.shipmentStatus, params.quantityAmounts);
final Receipt receipt = Receiplt(
procurementStore: procurementStore,
costCenter: const CostCenter(),
receiptItems: receiptItems,
shipmentId: params.shipmentStatus.Id,
receiptType: params.shipmentStatus.ShipmentType,
description: params.description,
operationPeriodId: 0,
receiptDate: params.date,
receiptTime: params.time);
return await shipmentsRepository.updateReceipt(receipt);
});
}
To extract left or right:
Left:
print(result.fold((l) => l, (r) => null))
Right:
print(result.fold((l) => null, (r) => r))
You can cast it but make sure u use isLeft / isRight first
final workflowUnload = await someEither();
if (workflowUnload.isLeft()) {
emit(state.copyWith.call(
status: JobOrderStatus.error,
failure: (workflowUnload as Left).value,
));
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.