In this lesson, we'll look at how we can use Ramda's
constructN functions to take methods of an object and turn them into reusable utility functions that are curried and accept their object as the last argument. We'll convert a dot-chained string of jQuery methods and create a composed function that can be applied to multiple elements.
Here, I have two divs defined, and I've pulled jQuery into the file. If I uncomment this code, it's going to run an animation on that first div. It's going to slide over, slide back, and then slide up and disappear out of view. I'd like to take this and put this in a reusable function so that I can run the same exact code on the other div, without having to redefine this entire .chain structure.
In order to do this, I'm going to pull in Ramda. I already have Ramda included, I'm just going to use destructuring to pull a couple of the functions out of the Ramda library.
I'm going to want invoker, compose, and constructN. I'm just going to stop this until we have the code done, we're not distracted by the animation. I want to keep this for reference, and the first thing I want to do is I want to redefine the animate function.
I'm going to do that by declaring something called animate, and for this, I'm going to use Ramda's invoker function, and invoker takes two arguments. The first argument is the number of arguments that our method is going to get before the object.
If we look at animate, animate's getting a single argument here, it's getting an object, and then once we have a reference to the object, we want to invoke this function. Our second argument is the name of the function to invoke, in this case, it's animate.
Animate is a curried function that's going to take an argument and return a function, and then, it's going to receive the object as its second argument, at which point it can execute.
The example we started with has animate running twice with two different arguments, we don't need to define it twice, we can use this multiple times with different arguments. Now, I just need to redefine slideUp. I'll just call it slide, and I'm going to use invoker again.
This time, sildeUp doesn't have any arguments, this function only needs a reference to the object as an argument, we're going to use 0 to say there are no arguments before we get the reference to the object, and then the name of the method which is slideUp.
Now that we have these defined, I'm going to drop down and I'm going to define a function that I'm going to call animateDiv, and I'm going to set this to equal a call to Ramda's compose, and I'm going to compose my two animates and my slideUp.
This is going to run from right to left, I'll define slide as my first argument here, followed by animate, and this is going to accept its first argument which is my object for the left position of 10 pixels, and then my second call to animate - I'm sorry - my first call to animate in the order this actually executes is my left with 250 pixels.
Now, I have this composition, all I need to do is call animateDiv on a jQuery object. I'll declare div for right now as my $, and then my ID selector for sample, and then I can call animateDiv on that jQuery object.
If I run this, my div will slide over, slide back, and slide up. So far so good. I'm going to stop this from running, and we can make some more improvements. I'd like to come in here, and I'd actually like to avoid having to instantiate a jQuery object to pass into my function.
I'd like my function to take care of that for me. I'm going to take this composition, and I'm just going to break it out so it's a little easier to read. What I'd like to do is add a starting point here, where I actually construct my jQuery object from the query selector. I'm going to call this jq, and we'll define that up here with const jq, and for this we're going to use the constructN function that we pulled in from Ramda.
I'm going to constructN and I'm going to tell it how many arguments I'm going to pass in before I expect to get an object back, which in this case is 1, because we're going to pass the query selector in, the actual constructor to run, which in our case is the $ because we're using jQuery.
Now that that's done, I can actually call animateDiv with my query selector, and I can get rid of that, and now if I run this, we'll see that everything's still working as expected.
The other thing I can do now, is I can reuse this function, because all it expects is a query selector, and I can run this on my second div.