Introducing Optional Helper0:00
Another new thing in Laravel 5.5 is the Optional Helper. So you'll find this in Illuminate\Support\Helpers. And yeah, let's take a look at this. Okay, provides access to optional objects. And you'll see here it just returns a new instance of an Optional class. Okay, so before we take a look at this, let's just review an example. Now here's something you'll run into quite a bit. Let's say you have a User and we have a relationship between users and profiles. So I could say, find the User with an ID of 1 and give me their Profile. And you can see in this case, it does return an instance of Profile.
Null Relationship Problem0:28
So I could say, find the User with an ID of 1 and give me their profile. And you can see in this case, it does return an instance of profile. However, in your own projects, you may run into situations where that relationship has not yet been created. Maybe the User hasn't filled out the profile section, in which case you'll have something like this. The User with an ID of 2 in this example does not have a profile. So in that case, the relationship returns null. Okay, so now imagine in your view, you want to spit out the User's location. All right, well, once again, if they have a profile, it's very simple.
Okay, so now imagine in your view, you want to spit out the user's location. All right, well, once again, if they have a Profile, it's very simple. Something like that. But if they don't have a Profile, you can no longer do this, right? Because profile, well, this is returning null. And now we're trying to say null location. And of course, that's not going to work. So what we end up doing in these cases is maybe something like this, where you say, well, give me the user. And then we'll say, if the user has a Profile,
where you say, well, give me the User. And then we'll say, if the User has a profile, then spit out their location or don't do anything, right? So this is pretty common. And usually when you see this, it's often a use case for using maybe a null object. And that way, User profile, on the condition that there is no profile, it just returns like a null implementation that simply adopts the interface. But rather than doing anything or fetching any data, it just returns null. Now, in Laravel 5.5, we basically have a generic implementation of that. Let me show you.
Using optional() in Views1:49
Now, in Laravel 5.5, we basically have a generic implementation of that. Let me show you. We can call optional, and then we fetch our user. So to reiterate, user, this person does not have a profile. And we can see it here. OK, so we'll say, give me the user's profile, but it's optional. So if this relationship returns null, I don't want everything to blow up when I then try to fetch their location or when I then try to call a method. So in this case, if we run it, yeah, we just get null. Whereas before, you would have gotten an actual error,
So in this case, if we run it, yeah, we just get null. Whereas before, you would have gotten an actual error, and your project would have blown up. So yeah, this is incredibly useful and should simplify a lot of your code. So once again, if we find a User who has a Profile, well, in that case, it's just going to defer like normal. But if they do not have a Profile and this relationship returns null, well, once again, it's optional. So anything we call on this, it's not going to do anything. And if we run that, as you can see, yeah, we get null.
How Optional Works Internally2:44
So anything we call on this, it's not going to do anything. And if we run that, as you can see, yeah, we get null. OK, so how exactly does this work? Very simply, in fact, it's not too different from the higher-order TAF implementation we reviewed. So let's take a look. When we call optional, we give it a value. So in our case, we are saying optional($userProfile). OK, let's see. All right, that gets assigned to this value property.
OK, let's see. All right, that gets assigned to this value property. And now you'll see we have two magic methods here for dynamically fetching the value of a property and then for calling a method. OK, so imagine let's just do this together. Imagine we give it foo. OK, well, now value is set to foo. So let's say optional(foo); and it's going to return null. So let's see what happens there. All right, we called a property.
So let's see what happens there. All right, we called a property. We tried to fetch the value of a property. So this triggers. key is now equal to bar. Notice in both of these cases, we only do something if the value is an object. So in this case, foo, that's not an object. It's a string. So anything we do, it does nothing whatsoever. That's fine.
Delegation for Objects3:47
So anything we do, it does nothing whatsoever. That's fine. However, if we have an object, like let's do this one here. Well, now at User find 1 profile, yeah, that returns an instance of Profile. So you'll see now when we try to fetch their location, yes, Profile is an object. So just defer to that key on the Profile object. And of course, the exact same thing is going to be true if we were to call a method on that object. So you can see it does exactly what it says on the tin.
if we were to call a method on that object. So you can see it does exactly what it says on the tin. The value you call is optional. If it's an object, we'll delegate. If it's null or something else, we won't do a thing at all. So yeah, I think you'll find a good use case for this with your relationships. But you can call optional on anything you want if it makes sense.
