Maybe This is Something We Should Know

Paul Ly
5 min readFeb 10, 2019

Ever found yourself continually having to manage null and/or undefined errors? I remember having to always write some conditional statements to account for the possibility of having something come in as such and prevent errors being thrown rendering the application useless and broken.

Especially when you’re working with external data and APIs, you can’t always trust that they’ll be accurate and reliable all the time. So you may fetch some data from an API and based on that data you want to manipulate and transform it before displaying it to your users. But what if all of a sudden the property that was always there, isn’t? Based on your code, it may throw an error like the following:

Looks like these folks are trying to call a specific method/function on some data that isn’t currently available. For a more specific example, imagine working with a picture API that has the basic title, description, uploader/author/poster properties that are returned. And you want to display this information to your users on your web app. Maybe the title is all lower case characters and you may want to capitalize each first letter like so: my awesome pictureMy Awesome Picture.

So when the user reaches this error page, it does nothing for them; the app crashes and they can’t get the data they requested and perhaps they’ll never come back! We can’t have that happen right? The user must be able to continue using the app no matter what and we can show kind error messages if need be — Sorry! The requested information is currently unavailable. Please try again later. This is quite a basic example, but it’s better — for me, and perhaps for you too — to keep it simple.

What can we do about this then? So glad you asked! I’m sure there are many ways to tackle these issues in various libraries, frameworks and external packages. Today I want to touch upon this Box ,Maybe , and Either concept provided by Ramda Fantasy and other similar packages and libraries. In order to start getting acquainted, start off with the first 2 videos from this course on Egghead. Initially it looks a bit silly and even perhaps old and outdated, but the instruction and the level of progression getting to the point he’s teaching on is fantastic!

Go ahead and take the time to watch those 2 videos now.

Box

  • allows for private state in each map block
  • fully compositional
  • provides an easier-on-the-eyes view of what’s happening

Maybe

The third video on that course goes into Either and that concept, and I understand why. But with no previous understanding of this sort of branching I think it can get complex real fast and think it may be easier to look at Maybes first.

This is what Ramda Fantasy ‘s docs state:

The Maybe type represents the possibility of some value or nothing. It is often used where null traditionally would to represent the absence of a value. The advantage of using a Maybe type over null is that it is both composable and requires the developer to explicitly acknowledge the potential absence of a value, helping to avoid the existence of null pointer exceptions.

This brings us back to earlier about handling null and undefined errors and the like. With Maybes you can easily tell and reliably manage your application without worrying it will crash and render useless to the users.

The documentation isn’t too bad, but the syntax isn’t to my liking and isn’t too intuitive for me; but at least some of the examples are great and straightforward for me.

lookup('foo', { foo: 'bar' })
This here is looking for a "foo" property in the object provided.
It is present and will return a Just because there is a value.
// => Just({ value: "bar" })
lookup('foo', { abc: 'bar' })
But here since there is no "foo" property on the object, it will return a Nothing.
// => Nothing()

Essentially I believe they are basic objects with a value property containing the, well, value or contents inside the Box. Whereas a Nothing is just an object with nothing. This way it will prevent any crashing due to null and undefined errors.

In order to get the value outside of the Maybe, you can tag on the getOrElse method. It really should be called getValueOrElse at the very least in my own opinion though. This way you can grab the actual value and if it is a Nothing then you can provide a default value to fallback on.

lookup('foo', { foo: 'bar' }).getOrElse('baz')
// => "bar"
lookup('foo', { abc: 'bar' }).getOrElse('baz')
// => "baz"

Either

As mentioned in the docs:

The Either type is very similar to the Maybe type, in that it is often used to represent the notion of failure in some way. The difference between the two is that an error represented with an Either can hold some value (perhaps an exception or error message), while Maybe can only indicate that absence of some value.

While the Either type is often used to represent potential errors, there is nothing restricting it to this purpose. It is therefore perhaps more appropriate to simply think of Either as a representation of two possible types of values, sometimes referred to as the disjoint union, or coproduct of two types.

A Maybe will return a Just or a Nothing right? You can think of it as returning one of two branches. Returning aJust indicates that there is some value whereas a Nothing means the lack of a value of course. Just — pun intended — like the docs says, Either is used in the context of error handling but can be used in more scenarios as well.

Take this opportunity to watch the third and fourth videos of the Egghead course to get a proper explanation! I had to rewind and playback some parts because my brain couldn’t keep up, but that’s ok! I think…The fifth video is also fantastic to see before and after examples. It gives you time to review the progressions and changes but I still paused so I could process.

As someone still relatively new to programming, this took a hot minute to grasp and to see the extent and implications it may have on a code base. But it definitely helps make the code more reliable! Working on a large project with many hands tackling their own issues or JIRA cards can be overwhelming and could lead to many human errors or lack of certain checks, but combine this with a typed language or Typescript and you’ve got a solid foundation!

--

--

Paul Ly

Full-Stack Web Developer - Former JPM Analyst, ESL Teacher, and Expat