Closed saltedpotatos closed 3 years ago
Hi @saltedpotatos!
I am missing a lot of context here and am a bit confused by some of the code you included, such as the seemingly unnecessary nested try
block in the third snippet and the purpose of yielding rather than just returning.
I also don't know the contract of OrderRepository
, making the desired error handling semantics very much guesswork :-) Below, I am assuming that every method on OrderRepository
returns Future<Either<SomeFailure, Order>>
values that should shortcut and fail the whole computation when Left
is encountered. You will have to adjust accordingly if that assumption is wrong.
I couldn't make any sense of the cachedOrder
stuff, so I omitted that below. Hopefully you can add it back in a way that works for you.
But... here's an attempt based on the Future<Either>
extension by @ResoDev that you linked to.
If you are interested in moving more towards an FP style, I believe that using Evaluation
instead of Future<Either>
directly would allow for a more elegant and natural solution.
final newOrderData = Order(inventoryId: e.inventoryId);
final processedOrderOrFailure = await _orderRepository.createOrderForLocation(e.locationId)
.flatMap((newOrder) => _orderRepository.createOrderForLocation(e.locationId))
.flatMap((recommendedOrder) => _orderRepository.patchOrderForLocation(e.locationId, recommendedOrder.id, newOrderData))
.flatMap((patchedOrder) async {
for(final item in e.orderItems) {
final addResult = await _orderRepository.addTransactionToOrder(e.locationId, patchedOrder.id, item);
if (addResult.isLeft()) {
return addResult;
}
}
return _orderRepository.getUpdatedOrderForLocation(e.locationId, patchedOrder.id);
});
yield processedOrderOrFailure.fold(
(l) => CreateOrderState.orderError(orderFailure: l),
(processedOrder) => CreateOrderState.orderUpdated(orderId: processedOrder.id, order: processedOrder));
I'm sure this doesn't do exactly what you need it to do, but I hope it at least gives you some pointers and/or ideas!
Thanks, @spebbe , your solution worked perfectly!
Sorry about the wall of text, and still not including enough context. I try and include enough information to avoid the xy problem , but still miss the mark sometimes.
I'll have to do more reading on flatmap vs map, since I assumed I wanted to map, and apparently I needed to flatMap, and also Evaluation, since looking at the classes signature, I am not feeling enlightened.
Do you accept donations? I appreciate the help!
Wow, that's great – your description clearly was pretty good then! 😃
Thank you very much for asking, but I don't accept donations.
Glad I could help – good luck with your project!
I've recently started using Either types, or any functional programming, and am stuck trying to figure out how to yield a state in my bloc when I need to perform multiple actions in an event, and call a function on each item in a list.
Everything works well if I'm performing a single action like
or
But I get lost trying to chain multiple calls.
Looking at some of the extension functions from ResoDev and Its1610 at issue #34 seems to get me closer, but I am not quite there.
For this event, I create an order, add an id to it, add a list of items to the order, and fetch the updated order to display. How I accomplished this before refactoring to Either, and just try catching exceptions was
Moving over to each repository function returning either success or an OrderFailure, I think this is how I should attempt this
And this will create an order, add an inventory id, but doesn't add any of the order items into the order. Also I feel like I can do this in a single map, but that also eludes me.
Thanks!