Reputation: 85
I have a flow of 2 nested request, where could be 3 different results:
Both requests could throw an error, and becaues of that implements TaskEither
const isAuth = ():TE.TaskEither<Error, E.Either<true, false>>
=> TE.tryCatch(() => Promise(...), E.toError)
const getProfile = ():TE.TaskEither<Error, Profile>
=> TE.tryCatch(() => Promise(...), E.toError)
The first request returns the boolean status of user authorization. Second request loads user profile if the user is authorized.
In return, I want to get the next signature, Error or Either with Anonymous/Profile:
E.Either<Error, E.Either<false, Profile>>
I tried to make it this way:
pipe(
isAuth()
TE.chain(item => pipe(
TE.fromEither(item),
TE.mapLeft(() => Error('Anonimous')),
TE.chain(getProfile)
))
)
But in return, I get E.Either<Error, Profile>
, witch not convenient because I have to extract Anonymous
status by hands from Error
.
How to solve that question?
Upvotes: 4
Views: 4534
Reputation: 1380
Don't know if you oversimplify actual code, but E.Either<true, false>
is isomorphic to just boolean
, so let's stick with simpler thing.
declare const isAuth: () => TE.TaskEither<Error, boolean>;
declare const getProfile: () => TE.TaskEither<Error, Profile>;
Then you add condition branch based on whether its authed or not and wrap the result of getProfile:
pipe(
isAuth(),
TE.chain(authed => authed
? pipe(getProfile(), TE.map(E.right)) // wrap the returned value of `getProfile` in `Either` inside the `TaskEither`
: TE.right(E.left(false))
)
)
This expression has type TaskEither<Error, Either<false, Profile>>
. You probably need to add some type annotations for it to typecheck properly, I haven't run the code myself.
EDIT:
You probably need to extract lambda as named function to get proper typings, something like so:
const tryGetProfile: (authed: boolean) => TE.TaskEither<Error, E.Either<false, Profile>> = authed
? pipe(getProfile(), TE.map(E.right))
: TE.right(E.left(false));
const result: TE.TaskEither<Error, E.Either<false, Profile>> = pipe(
isAuth(),
TE.chain(tryGetProfile)
);
Upvotes: 4