Enter Your Email Address to Watch This Lesson

Your link to unlock this lesson will be sent to this email address.

Unlock this lesson and all 960 of the free egghead.io lessons, plus get JavaScript content delivered directly to your inbox!



Existing egghead members will not see this. Sign in.

Refactor to Point Free Functions with Ramda using compose and converge

3:33 JavaScript lesson by

In this lesson we'll take some existing code and refactor it using some functions from the Ramda library, most notably, compose and converge. When we're done, we'll have taken a function with a couple of local variables and parameter references and converted it into more streamlined "point-free" or "tacit" functions.

Get the Code Now
click to level up

egghead.io comment guidelines

Avatar
egghead.io

In this lesson we'll take some existing code and refactor it using some functions from the Ramda library, most notably, compose and converge. When we're done, we'll have taken a function with a couple of local variables and parameter references and converted it into more streamlined "point-free" or "tacit" functions.

I've included the Ramda library and I have a person object defined. I've also defined two functions, one to take an ID value and return a URL string that includes that ID and another that takes the person object, gets a URL using the first function, and returns a new person complete with an avatar property. If I jump over to the terminal and I run this, we'll see that everything works as expected.

Let's take a look at how we can refactor this code. There's a problem with how I'm calling generate URL. If there's no ID value in the object passed in, we'll get back undefined. But it would be better to show a default image if the ID is undefined.

Let's come up here and refactor this. We'll use Ramda's prop or function to define our default values. We'll use the string default. Then, we'll try to get the ID. We want to get that ID off of the person object. I'll take this reference to ID out. This'll work, but we can clean this up even more using compose.

I'm going to come over here right before generate URL. I'm going to call r.compose. I'm going to pass it in the generate URL function followed by a call to R.propor. Then, I'm going to close this off right here.

What we've done with compose is created a function that will take your arguments and pass it in from right to left. A person will get passed into propor, will get our ID or the value default. That'll get passed to generate URL, and then our URL assignment over here'll get the resulting value of that.

Now that we have this contained in a function, I can cut that, come up here, define this as a new function. We'll call get URL from person, assign it there, and then, we can just use that right here with our person object.

Now that we've broken this down, we can tighten this up a little bit. If we want to take this get URL from person here and we'll cut it, we'll just replace our URL value with that, we can actually get this function down to one line.

We'll remove this return because we're using an arrow function. I'm just going to stretch this window out a little bit so we can see the whole thing.

We've managed to break this out into a couple of single line functions. We got rid of that URL variable. But we're left with this function that has nested function call and a couple references to this person parameter. We can clean this up and completely remove the person parameter. To do that, we'll use Ramda's converge function.

I'm going to start by duplicating this line, commenting out the other one for reference. I'm going to come in here, and I'm going to get rid of this call to person. I'm going to replace that with a call to r.converge.

I'm going to jump to the end of avatar. I'm going to close the parens for r.soc. This is going to give me a function that's now waiting for two arguments because all of these functions are automatically carried.

The second argument for converge is going to be an array of transformation functions. I'm going to wrap get URL from persons square brackets. I'm going to get rid of these references to person.

What's going to happen is our person argument's going to be passed in. It's going to be passed to each transformation function which is going to give us an array of results and that array is then going to be passed in as arguments to this first function here.

What we need is get URL from person which is going to take a person, it'll get the ID, generate a URL. It'll pass that in as the second argument here.

Then, we need one more transformation that's going to take person and basically just pass it along as is. For that, we can use Ramda's identity function that'll take whatever argument gets passed in and just return it.

With all the refactoring done, let's save this. We'll jump into the terminal and we'll make sure this works. Everything's working as it did before, but we're doing this with a point free function and no extra variables are required.

HEY, QUICK QUESTION!
Joel's Head
Why are we asking?