My DAO method types are:
ProductDao.getById(..): ConnectionIO[Option[Product]]
InventoryDao.getById(..): ConnectionIO[Option[Inventory]]
The function I need to refactor to make it safe is below:
def getInventoryLocation(...): IO[Either[String, Int]] = {
(for {
product <- EitherT.fromOptionF(ProductDao.getById(id).transact(xa), "product not found")
inventory <- EitherT.fromOptionF((InventoryDao.getById(product.inventorySectionId.get)).transact(xa), "product not found")
} yield inventory.location.get).value
}
There are 2 problems currently with the function, it calls .get
two times.
I need help removing those, when I try .map over the option that doesn't seem to work correctly.
inventory <- EitherT.fromOptionF(( product.inventorySectionId.map(InventoryDao.getById()) ).transact(xa), "product not found")
Because then I am returning a None and not a IO none I guess?
Your for-comprehension already uses an
EitherT
for error handling. Assumingproduct.inventorySectionId
andinventory.location
returnOption
s, you can useEitherT.fromOption
to make them compatible and put them into separate lines in thefor
, so you no longer have nested errors: