Curry Cooking
A practical use of a curried function
Remember a couple of weeks ago when a wrote a blog post about currying functions? That theoretical post was like writing a recipe. Now, it’s time to get cooking.
I was checking out the adapter file in an app I built called The Shed last week and as I was scrolling through, I noticed that the code was not very DRY (Don’t Repeat Yourself). Let’s take a look at a couple of functions:
I noticed that I was rewriting the same fetch
function with the same API_ROOT
(API_ROOT
and HEADERS
live in the constants folder of this app) for the url argument and similar request objects as the second argument. The only difference between postNewBand
and updateNotes
is the method
property. There has to be a way to make this cleaner! Why type almost the exact same thing twice? After all, we’re programmers and we are lazy!
Let’s break down this problem by looking at our request object that we are passing to fetch
. We want a request object with a method
, headers
, and a body
. But the method will depend on what kind of request we are sending to our server. If we make a request function that took in a method and data for the body and returned us an object, that would work.
That’s better. We are now using our req
function to return a request object with the correct method
passed in, saving ourselves from writing the same request object over and over. But check out ‘POST’
. We are writing that twice in two different functions. As our application and number of resources grow, we will find ourselves writing ‘POST’
over and over again to communicate with our server. That is too many POSTS!
We only have a select few HTTP verbs to choose from: GET
, POST
, PATCH
, PUT
, and DELETE
. The body of our request in this application is dependent on user given data and will always be variable. What if we wrote a function that takes an HTTP method as an argument and returns a function bound to that method, then that function takes in our data as an argument later on in our program and returns the correct request object? HUH?!?!?! WHAAAAAA?!??!
This is a job for a curried function with an assist from a closure. Check it out and relieve your sanity:
Now our req
function returns a function that will be bound to the method that we pass to req
. We save that function to a variable. So postReq
will point to a function that will take in some data
, stringify
that data
and return an object with a method
of ‘POST’
. We made a generic 'POST’
request object that we can now use as a second argument to our fetch method with any resource. The same applies for patchReq
.
That is awesome! A practical use for our a currying function! Our job here is done……
BONUS: LET’S GET THIS ADAPTER BONE DRY
Our postNewSetSong
and postNewBand
functions are almost identical! We have a fetch
method with a route, our postReq
function that returns our request object, and the data. Let’s do a couple of things. Let’s magically abstract our routes for bands
and set_songs
into a constants file (where API_ROOT
and HEADERS
live) and make a generic postResource
function that returns a fetch
function to communicate with our server bound to the to method: ‘POST’
. It will take a route
and data
as arguments. We’ll clean up a little syntax while we are at it.
This looks good and DRY to me!
Thank you for reading! Did you enjoy the blog? Have an opinion about the code? Have a suggestion to improve the code or an idea for further exploration? Please leave a comment below and let me know! Let’s connect on Twitter and LinkedIn! Thanks again and stay learning!
Check out some more of my writing below!
https://medium.com/@sethbarden/morris-date-and-the-time-14d1814f9452