_.get is by far my favorite lodash method. I've been on so many projects where the results of a network call was a large and often unreliable blob of data. After countless attempts to reign in errors caused by trying to access non-existent properties I've come to rely on _.get as a simple & safe way to retrieve data from those objects. However, as is always the case in web development, times are changing and the tools we need to safely access properties of complex objects are now being built into the platform. Optional chaining syntax gives us the power of _.get without several of the tradeoffs. It doesn't require an extra library to use, it plays nicely with TypeScript and it can be used when calling methods as well as when accessing properties.
This lesson covers 4 common use cases of
lodash.get and converts them to using optional chaining syntax.
Jamund Ferguson: [0:00] On the left-hand side of the screen here, I have a data structure with nested arrays, objects, [inaudible] , strings, and numbers. Below that I have several examples of using lodash.get which will replace with optional chaining syntax.
[0:12] For the first example, I'm going to look at accessing nested objects and arrays. Here are three different examples of using lodash.get to access this H2O molecule deeply nested in our object here. Let me log the results.
[0:24] You can see that for each of these, the results of the string H2O. Let's reproduce that with optional chaining syntax. Type const molecule4 equals data.collection?. ?.nodes?.molecule and log the result.
[0:41] When I run the command, you can see the result was exactly the same as what was provided by the Lodash methods. Let's move on to accessing properties with strings and variables. Here we have two different examples of accessing properties with strings and variables.
[0:55] In this, we're accessing the max-temp variable found inside of our node object. We do so with the max-temp property access are here and then below that, with a variable called key which has a variable max-temp. If I log that out, you can see that both temp1 and temp2 are the number 100 which is correct.
[1:15] To recreate this with optional chaining syntax, type const temp3 equals data.collection?. ?.nodes?.[key] and we log that. When we run the command, our result was exactly the same as what Lodash had.
[1:34] Now, let's do the same thing with the string accessor. We can create temp4 and instead of key, put max-temp as a string inside of this square bracket notation. We then log that and once again, the result is exactly the same.
[1:49] Let's look at looping through an array which may or may not exist. To do that on Lodash, we will grab an array and if it does not exist, return a default value of empty array. We say that to a collections variable and then loop through that collections variable and log each item.
[2:04] The results of that are a list of every single one of collections in our data structure. Let's go ahead and reproduce this with optional chaining syntax by typing data.collection?.forEach and then pass in the same logging method that we did above.
[2:20] Let's log that. You see that first we log with Lodash and then we log with our optional chaining.
[2:25] The cool thing about this is that we didn't need to save a variable the second time around. We were able to access the forEach method on collection simply using ?. and if we go to our collection and rename this to collection123 and rerun it, you'll see that no errors are thrown.
[2:41] It's a completely safe way to execute a method on an object even if that object may not exist.
[2:47] For the last example, I'd like to go over providing default values when a value is not found. For this we're going to look through the second collection, the fourth collection, and then the hasDetails property of collection three. Let's log out what this looks like now.
[3:00] You'll see that collection two is null and so instead of providing a default, it just returns null. Collection four was undefined so that is replaced with the empty object we passed in. Then hasDetails is false and correctly returns false instead of the true default which we provided.
[3:18] Accessing the data with optional chaining is easy. Let's do that now. Type const col_2 equals data.collection?. . We'll do the same for collection four, and for hasDetails. Const has_details data.collection?.?.hasDetails. Let's just log those to ensure that we got them properly.
[3:46] You can see that it's null, undefined, and hasDetails is indeed false. Optional chaining itself doesn't provide a mechanism for providing default value but there are two options. The most common one is to use the or syntax.
[3:58] We'll do that first. Put col_2 or empty object, col_4 or empty object and hasDetails or true which is the default. Let's log that. You'll see here that the results are fairly different from what we had before.
[4:13] Collection two shows an empty object instead of null. Collection four shows an empty object correctly, and for hasDetails we get true instead of false. Why is that? Because if the or operators encounter any falsy value on the left-hand side of the operator, it will return whatever is on the right-hand side.
[4:30] If it's an empty string, undefined, null, the number zero, any of those things will return your default value. Now that works fine if you're expecting array or an object, but if you are expecting a Boolean which may be false, you can't use or. Instead you need to use something else.
[4:55] With the nullish coalescing operator, it only will return the value on the right-hand side of the operator if the value on the left-hand side is null or undefined which is actually what we want in most cases even if it doesn't exactly match what Lodash was doing before.