lodash is a popular javascript library with a set of utilities. One of the utilities that lodash provides is the get function which, as the name suggests is used to get a value from an object. Let us see an example:
Suppose there is an object
let response = {
data: {
options: {
name: 'Bojack'
}
}
};
Now if you wanted to get the name
from the above object, you would typically do it like this:
const name = response.data.options.name;
console.log(name);
And this will work and output the name Bojack
. No Worries, Right?
Well, for the most part, it is. Let me explain. Say, for example, this object is a response from an API and because the coding gods are angry on you, the object has a structure different from what you think it will be. The key options
in the data
object is now called user_options
and the code you've written does not account for that. Now If you run the code to get the value of name this is what will happen:
Since data.options
is undefined
and you are basically trying to access the name
property of undefined
, you end up with a TypeError
.
To make sure you do not end up in such a situation, you have to put up safe checks in your code. For example, to avoid the situation described above, we can do something like this:
const name = (response.data && response.data.options && response.data.options.name) || 'Todd';
This will make sure that if at any level of the object, the property you are trying to access is undefined
, you do not try to access properties further down the chain and thus, do not end up with a TypeError
. Also In the above statement, if the property we are trying to access is undefined, Todd
gets assigned to the name which kind of acts as a fallback value.
However, as you can clearly see in the code, for large objects, the above code segment can be very cumbersome to implement.
Enter lodash.
lodash's get
function lets you easily implement safe checks while getting data from objects. If we use lodash for the above example, we can do it like this:
const name = _.get(response, 'data.options.name');
This will make sure that you do not end up with errors and also don't have to write complex accessor chains like in the example before this one.
Another beauty of the lodash get
function is that you can specify an optional 3rd argument which is the default value to return when the property you are trying to access is falsy. For example,
const name = _.get(response, 'data.options.name', 'Todd');
will return Todd if the options
key on data
does not exist.
So we solved both of the problems we ran into while writing property accessors.
Win-Win right?
Well, not exactly. lodash is essentially a 3rd party dependency and you must have heard the saying mo dependencies, mo problems
. Some of these problems include increased bundle size and the responsibility of keeping dependencies up to date.
However, there seems to be a solution coming up in javascript itself. There have been two proposals to add the following two features to the language itself - optional chaining and nullish coalescing.
Let us see how these language features can help us in replacing lodash with native javascript.
Optional Chaining:
As also shown above, this is how you would safely access the name
property from the response object.
const name = _.get(response, 'data.options.name');
This is how you can do it without lodash by using optional chaining:
const name = response?.data?.options?.name;
The above statement behaves similar to how our code with a lot of &&
safe checks would behave, but looks a lot cleaner!
Nullish Coalescing:
So we now have safe checks in property accessors, but what about default values, If I am unable to find the name property, I want to assign the name Todd
to the name
variable.
Here is how you can do it by using Nullish coalescing:
const name = response?.data?.options?.name ?? 'Todd';
In the above statement, we combined the use of optional chaining and nullish coalescing to achieve the same result that we were getting by using lodash or making the use of &&
and ||
operators. If I am unable to access the property name
from the response
object, due to optional chaining, the name will have the default property Todd
thanks to nullish coalescing.
So Can I go ahead and replace lodash.get
in my app?
Well, not really. As of today, 15th of December, 2019 Both the new JS features we talked about in this article are only at stage 3 of the tc39 proposal. This means that it will take a while before it ships in all browsers and we can use it. However, you can also use the following babel polyfills to use these features ahead of time - 1 and 2.
Further Reading/References -
Top comments (1)
github.com/tc39/proposals/blob/mas...
Actually both reached stage 4