Let's learn about
an even newer feature of objects and also of arrays
which is called optional chaining.
And this one is really amazing.
So, let's say that we wanted to get the opening hours
of our restaurant for Monday.
So let's quickly check that.
So restaurant.openingHours,
and then since we are checking for Monday,
let's try .mon.
So which could stand for Monday.
Now, actually this property doesn't exist.
So you see that this is undefined, right?
But let's pretend that we do not know
whether this restaurant opens on Monday or not.
And that could be the case.
For example if this data came from a real web service.
So a web API.
And in their service there could be multiple restaurants
and not all of them would open on Monday.
And so we had no way of knowing
if this particular restaurant
would open on Monday or not.
But now let's go even further
because we actually want to know exactly the hour
on which the restaurant opens on Monday.
So let's see what we get.
And now we do actually get an error
because the results of this was undefined.
And then undefined.open is really an error.
So that's the error that we get here.
So in order to avoid this error,
we would first have to check if this here actually exists.
So we could do something like this.
If this property exists, basically then do this.
Or we could also use a logical operator
as we already learned
but this here is a bit more readable, all right?
So if we did the same for
let's say Friday,
then we already know that Friday exists.
And so this would then work
and it would be 11.
But let's focus here on Monday,
which is the day that doesn't exist.
And so now at least we got rid of our error here.
So it's not a big deal to having to add this logic here
but it does make our code a little bit more unreadable
and more messy.
However, this is checking just for one property.
So just for Monday.
But now imagine that opening hours here
would also be optional.
Or in other words that maybe the restaurant object
can also not have opening hours.
So, in this case, we would have to check for both, right?
So we would have to do
if restaurant.openingHours exists
and if restaurants.openingHours.mon exists
while only then unlock the opening hours to the console.
And this can get out of hand pretty quickly
when we have deeply nested objects
with lots of optional properties.
And sometimes that happens in the real world.
And so therefore ES2020
introduced a great solution for this,
which is a feature called optional chaining.
And with optional chaining,
if a certain property does not exist,
then undefined is returned immediately.
And so that will then avoid
that kind of error that we saw earlier.
And this is how it works.
So let's recreate it now with optional chaining.
(keyboard clunking)
So now we can say restaurant.openingHours.mon
and now here is the optional chaining operator.
So instead of just a dot,
we use question mark, dot and then open.
Okay? So here is how optional chaining works.
So only if the property
that is before this question mark here.
So only if Monday exists,
then this open property will be read from there.
All right?
But if not, then immediately undefined will be returned.
And exists here actually means the nullish concept
that we already talked before.
So, a property exists if it's not null and not undefined.
Okay?
So if it's zero or the empty string,
then it still exists of course.
So if we try this now, then we get undefined.
So that's exactly what I was saying.
Let's just, again, recreate it here
without the optional chaining.
Just to see the error again.
And so here we would indeed get the error.
Again because all of this here is undefined,
and then we read open here from undefined,
which doesn't work.
But here this next operation of trying to read open
only happens if all of this here actually exists.
So if it's not null and not undefined.
But if it is undefined or null,
then the result will be undefined immediately.
So let's take this out again.
And so that is why we get undefined right now.
And of course we can have multiple optional chainings.
So let's basically recreate what we have here.
So in this example,
so here we are testing for both opening hours
and for Monday.
So these are essentially the two optional properties
that we do not know beforehand if they exist.
So Monday is optional,
and that's why we have the question mark here basically,
asking if it exists
and now we can do the same for opening hours.
And now if restaurant.openingHours does not even exist,
well, then the Monday property will not even be read
and so therefore we don't get that error.
All right?
And so this makes it really easy
to prevent all kinds of bugs
that sometimes we might not even expect.
All right?
So, it also takes away all this work of doing this
simply by adding this simple question mark in there.
But now let's see a little bit more real world example.
And for that, let me grab this
weekdays array and put it here.
(keyboard clunking)
Let's just call it days here
so it's not the same variable.
And now what I want to do is to loop over this array
and then lock to the console,
whether the restaurant is open or closed
on each of the days.
(keyboard clunking)
So, that's a good application
of optional chaining right there.
(keyboard clunking)
So let's start just by logging here today
just so that you can remember how this loop works.
And so indeed now we can do some code
with each of these days here.
So, let's now essentially do the same as we did up here.
So restaurant.openingHours
but now we cannot do this, right?
Because this is not an actual property name of the object.
And so remember if we want to use a variable name
as the property name,
basically, we need to use the brackets notation.
So we learned about this way back
in the fundamental section.
And so make sure to remember that.
Okay?
So, basically this would be the same in the first day
.mon and then .tue and so on and so forth.
But the day here is coming dynamically from this array.
Okay?
But optional chaining of course also works with that.
And so now we can ask if open exists, basically.
And now let's save this to a variable
and then let's log to the console.
And this is not yet complete
but for now, let's see what's gonna happen.
So, on day and then whatever is the current day
we open at,
and in here we use the open variable that we just created.
Let's get rid of this console.log here.
Okay.
So, we get on Monday we open at undefined,
undefined, undefined,
and then indeed on Thursday, Friday and Saturday,
we are open.
And so then we get the opening hour
that is actually also in the object.
Let's just make sure.
So this one is open 12, 11 and zero.
So essentially it's open 24 hours.
It opens at 12 and closes at 24.
So at midnight again.
All right? So that's working.
But now we don't want this undefined here. Okay?
And so just like before
let's set a default value.
So let's use or,
and so as a default, we want to say closed.
So we are open at closed.
So that doesn't make a lot of sense.
So we could create a better sentence there
but let's leave it like this.
But maybe you're noticing that now we have a problem
which is that on Saturday it says that we are closed.
Although actually we open
or the restaurant opens.
So here on Saturday which is this one,
indeed, this property exists.
So there is a property called Saturday.
And so we have a problem here.
And the problem is that the restaurant opens at zero.
And so here we have the same problem as before
where zero is a falsy value.
And so therefore it will then trigger this second part
of the operator.
But we also saw the solution to this,
which is to use the nullish coalescing operator.
And so that's what we do now.
And now we get back to open at zero.
Great.
So, this is an amazing use case
of the optional chaining operator
and the nullish coalescing operator working together.
And in fact, they were introduced into the language
at the same time in ES2020
because they were really designed
to work well with each other.
So again, both of them rely on this new concept of nullish
and so nullish values are null and undefined.
And that's it.
And so that's true both for this nullish coalescing operator
and also for optional chaining.
Okay. Great.
Now that you understand how it works,
let's move to the next topic, which is on methods.
So optional chaining does indeed also work
for calling methods.
So, essentially we can check
if a method actually exists before we call it.
So, restaurant.order,
and now we can check if it exists.
So we use the question mark, dot, and if it does exist,
then we can call it.
So let's just pass zero and one here.
And then we should always use together
the nullish coalescing operator.
And so, method does not exist.
So let's run this
but in this case, the method does actually exist.
And so here we get the expected result.
When we try to call a method that doesn't exist.
So let's say orderRisotto,
and so we never wrote a method for that.
And so, let's see.
And yeah, now we get method does not exist.
And so just like before
this optional chaining operator
will check if orderRisotto actually exists.
And if it doesn't,
well then it will immediately return undefined.
And so all of this then returns undefined.
And so here in the nullish coalescing operator,
we immediately go to that second operant.
So that's this one here.
And yeah, then that's the result of this whole operation.
So of course, if we hadn't this,
then we were trying to attempt
something that is not a function.
So really useful on methods as well.
And finally, optional chaining even works on arrays.
(keyboard clunking)
So basically we can use it to check if an array is empty.
So let's simply create a users array
in which we can put a couple of user objects.
So name Jonas
and email,
hello@Jonas.io.
(murmurs)
This is just for demonstration.
So let's just put one object here
and now to get the name of the first element of this array,
we can do this.
We can write users, element number zero
and only if it exists.
So, optional chaining only then take its name.
Okay?
And otherwise we want to log user array empty.
So let's see.
And indeed we get Jonas.
And so again, this optional chaining here
tests if the value on the left does exist.
So users zero.
Okay?
So if it was empty,
so users,
so like this,
then we get user array empty.
And without optional chaining,
we would have to write something like this.
So if users.length
greater equals zero
then console.log
and this here
and else console.log,
user array empty.
All right?
And so that looks like a lot more work
than what we just have up there.
So, here we don't need to do any check
so that's a lot better.
And so now in both cases, we get Jonas.
So, get used to this optional chaining operator,
which almost always,
we use them together with the nullish coalescing operator
so that we can actually do something
in case we don't get a result from the object
or from the array that's here on the left hand side.
All right.
And with that being said, I see you in the next video.