Either Monad — Async Error handling

Dimitris Papadimitriou
2 min readNov 13, 2019

source fiddle : Asynchronous functional javascript using either-async

In my opinion, by using just two functional patterns those of Maybe and Either we can dramatically improve the quality of our code and reap the majority of benefits of a Functional programming style

Using Either to replace try/catch blocks is part of the natural progression of JavaScript (and every object-oriented language)

In this realistic example, I am going to display the scenario where we want to find an employee assigned to a client. The only prerequisite in order to follow the article is to be aware of the Either monad functional pattern. You can find more here :

lets see the repository for the clients first

a lot of stuff happening here.

  1. The mockFetchAsync returns a new Promise() of an array

After mockFetchAsync().toEither() this promise is now transformed into an EitherAsync type this exposes the exact same methods of an Either. This will potentially result into an array or an error. EitherAsync is lazy, and it wont evaluate even after the Promise have finished execution. That’s until we use the cata method to fold the EitherAsync

eitherAsync
.cata({
ok: data=> console.log("result: " + =>),
error: error => console.log("error: " + error)
});

From now on we can forget that we are working asynchronously. We just assume we have a synchronous Either. The next step is to get the first element of the array that matches the id , we are going to use the filter and the safeHead that return a maybe ([_]) (learn more about maybe here)

response.filter(c => c.id == id).safeHead()Array.prototype.safeHead = function () {
return this.length > 0 ? some(this[0]) : none()
}

we can make a Maybe into an either by providing a default message, if there where no clients found

data.filter(c => c.id == id)
.safeHead()
.toEither(`there is no client with id ${id}`))

now since this is an either we must use bind and not map in order to access the result of the fetch since this is also an Either. So this whole block finally becomes

getById: (id) =>
mockFetchAsync()
.toEither()
.bind(response => response
.bind
(data =>
data.filter(c => c.id == id)
.safeHead()
.toEither(`there is no client with id ${id}`))),

beautiful !!

Try to write the same using try/catch and async/await.

Now for the second part we are going to have a similar Employee repository call and get an Either[employee]

then we are going to use again bind to Either[Client] and Either[Employee] and get the final result :

--

--

Dimitris Papadimitriou
Dimitris Papadimitriou

No responses yet