Check out a free preview of the full Introduction to Elm, v2 course:
The "Optional & Nullable" Lesson is part of the full, Introduction to Elm, v2 course featured in this preview video. Here's what you'd learn in this lesson:

Richard introduces the concepts of Nullable and Optional Decoders that allow for optional or nonexistent fields in JSON data.

Get Unlimited Access Now

Transcript from the "Optional & Nullable" Lesson

[00:00:00]
>> Richard Feldman: Another thing that could happen is that we can get some JSON that has null in it. That's not a concept in Elm, Elm doesn't have null, but JavaScript and by extension JSON absolutely have it. So how do we handle it when we receive something like that? Another question we might have is, what happens when we have a field that is optional?

[00:00:17] In other words, sometimes it's going to be present and sometimes it's not. So here we have a different data structure that we're decoding into, a different version of user. And also some different JSON that's going to be going into it. So in this JSON, we have a user ID, which is an integer, just like before, we have a name field, which in this case is null.

[00:00:35] And on the Elm side, we say, okay id is going to be the integer, just like before, name is maybe going to be a string, maybe not. But email is something we explicitly expect to always be set. However, it's not present in the JSON, this JSON does not include an email address, so how do we handle these things?

[00:00:53] Well we start off essentially the same way as we did before. We're saying we're going to make a user that's going to be a Decoder User. We'll start off with Json.Decode.succeed, once again, passing in User, which is going to be a function that takes an Int. And this time a Maybe String and then a String and finally returns a User, so far, so good, same as before.

[00:01:11] The first step we're going to do is we're going to decode the user_id again, same as before, because there's no change. It's present, it's always going to be present, and it's going to decode directly from an Int on the JavaScript side to an Int on the Elm side.

[00:01:23] No change there, there is necessarily going to have to be a change here for two reasons. One is, on the name side, on the JSON side, name is null, and on the Elm side, name is a Maybe String. Fortunately there is a decoder combinator called nullable. And so nullable is a function that takes a decoder and returns a maybe version of whatever that thing decodes to.

[00:01:50] So just like we saw you could have a list string which gives you back a decoder of a list of strings. You say nullable string, that takes a decoder string and gives you back a decoder of maybe string. And as you might guess, the way that it decides whether to use a just or a nothing, depends on whether the value is either null or not null.

[00:02:09] So, in this example, because name is coming in as null, that will come in as nothing on the Elm side. If on the other hand, name had come in as a string, that would come in as just and then the string on the Elm side. So, an important implication of this is that we have to say upfront whether or not we expect null to be coming in from JSON here.

[00:02:28] So we're saying this is explicitly nullable. Whereas Int, we say null is not okay, if we'd had an Int in this field, this would fail to decode. Finally we have to deal with the fact that email is something that we require on the Elm side. But which is not actually present on the JavaScript side.

[00:02:44] One way we could do this, which is something we'll see in the exercise, is there's something we can say called hard coded. Which says, you know what, just ignore the JSON, always put this value in, but we want to do something slightly different here. What we want to say is, here's what to do if email is present.

[00:02:59] And then also here's what to do if email is not present, we're going to provide a fallback. And here, instead of saying required, we say optional. So we're saying, we have an optional field, called email, and if that field is present, we expect it to be a string.

[00:03:13] And if that string is present, then we're going to use that as our value and it's going to go into this email thing right here. However, if that value is not present, we're going to fall back on this default value, me@foo.com. So because the email field is not even present in this JSON object, that's okay.

[00:03:33] It just means that we're going to use this fall back and that value is going to be what's going to get set to User. So between all these things we have user_id being set the same way as before. We have this nullable string, which handles the possibility that name is either null or not null.

[00:03:47] And that corresponds to this name field up here. And finally we have the optional email string, which is going to look for a field called email. But if it's not there, it's going to fall back on this value. So in that way we're able to handle even these edge cases of JSON of null, of fields being missing.

[00:04:03] And still consistently decode into either this user or if anything went wrong in any of these steps. Fail the decoding and then we will handle that the same way that we did before.