Join egghead, unlock knowledge.

Want more egghead? It's 45% off for a limited time only!

This lesson is for members. Join us? Get access to all 3,000+ tutorials + a community with expert developers around the world.

Unlock All Content for 45% Off

Already subscribed? Sign In

Save 45% for a limited time.

Get access to all courses and lessons on egghead today.

Autoplay

    Get Deeply Nested Properties Safely with Ramda's path and pathOr Functions

    Andy Van SlaarsAndy Van Slaars

    In this lesson we'll see how Ramda's path and pathOr functions can be used to safely access a deeply nested property from an object while avoiding the dreaded checks for undefined at each new property in the desired path.

    ramdaRamda
    Code

    Code

    Become a Member to view code

    You must be a Member to view code

    Access all courses and lessons, track your progress, gain confidence and expertise.

    Become a Member
    and unlock code for this lesson
    Transcript

    Transcript

    00:00 Here I have two objects representing departments in a company. As you can see, the AccountingDepartment is much more complete with a personnel section which includes a manager, with a first name, last name, title, and salary. The ITDepartment just has the name and location. Our result is the last name of the manager under personnel for the AccountingDepartment, and if I run this, we'll see that I get the last name printed out.

    00:22 If I change the AccountingDepartment to the ITDepartment, however, my output's going to go away, and if I open my console we can see that's because I have a type error, cannot read property manager of undefined. The problem here is that personnel is not defined in ITDepartment, so we get an exception.

    00:40 In order to make this a safer operation and avoid this exception, what I could do is I could come in here and take ITDepartment.personnel. I could add a check for that, and if that's truthy, then it will evaluate the next part, so if my ITDepartment now has personnel, but it still doesn't have manager, we'll see I get a type exception again.

    01:09 What I can do is I can come in here and then I can add another check for ITDepartment.personnel.manager, and another double ampersand, and I'll get back undefined. At least I'm not getting the exception anymore, but the problem here is if I want to be able to do the same thing with the AccountingDepartment, now I need to take all these checks and basically duplicate them for the accounting department. I could take this and I could wrap this all up in a function that would work on anything with this particular path, but there's a better way.

    01:41 What I'm going to do, is I've included Ramda in this file, so I'm just going to use destructuring to pull in some functions. I'm going to start with path, and then on my result what I can do is actually call a function that I'm going to create using path, so we're going to call it getManagerLast.

    02:01 I'm going to use Ramda's path, and path is going to take two arguments. It's going to take an array of property names, and those property names are going to be the properties that we are calling with our path here.

    02:14 We're going to do personnel, followed by manager, followed by whole name. Now getManagerLast, because it's a curried function, is going to return a new function that's waiting for its second argument. In our case that second argument is going to be the object that we want to get that value from. I'm going to come down here and I'm going to call getManagerLast and I'm going to pass it ITDepartment, and I can get rid of the rest of this. We'll see that I get back undefined.

    02:49 I didn't have to do all those checks. The property still doesn't exist in ITDepartment, but it's doing what it's supposed to do. If I switch this back to the AccountingDepartment, we'll see that we get the expected value. Now this operation is much safer. I've avoided the error, but I don't necessarily want to get undefined. From passing in the ITDepartment it's great that the exception doesn't get thrown anymore, but I want a value here.

    03:15 What I can do is I can just use || to say or, and if it's not a truthy value I can just say nobody, and that works, or I could make this part of my getManagerLast function. What I can do is I can take this out of here, get rid of those double pipes, and I can pull in another function from Ramda called pathor. Pathor is going to take my array as a path, but before that, it's going to take a default value. I'll pass in my nobody string, followed by my array.

    03:50 I'll get back a function I can pass an object to, and it will either get the item on the path, like the AccountingDepartment where I get my value, or it will get undefined and replace it with that default value.

    Discuss

    Discuss