JavaScript Simple and Elegant Function Chaining

A very simple Array prototype that chains functions listed in it via function outputs. This is not an object function chaining. It just connects or pipes function outputs to the next function in the array.  It is a short and simple snippet, that eliminates a lot of brackets and improves readability and encourages small (max 5 lines) reusable functions.

Let’s say we have several functions:

function a(str) {
   return 'foo'+str;
}

function b(str) {
   return str+'bar';
}

function c (str) {
   var w = 'baz';
   return w+str+w;
}

And we want the result from function ‘a’ to pass to function ‘b’, and result of ‘b’ to pass to function ‘c’. We can do it traditionally with a lot of brackets, and we can get lost in them resulting in those stupid syntax errors we all hate:

alert(c(b(a('qux'))));
//prints "bazfooquxbarbaz"

Ugly isn’t it? As I am trying to stay modular as much as I can, and to force the rule of small reusable functions, that are readable on the sight without much thinking, I was struggling with this silly issue because i was bored to write the following code. And one day I got pissed and I just wrote this:

The noted Array prototype passes any arguments passed to it to the first function, result of the first function passes to the second, and so on until the last one. Now this looks more readable, you have to admit.

alert( [a, b, c].chain('qux') ); //chain of foos
//prints "bazfooquxbarbaz"

Lets make matters more complex, shall we? Let’s say we want to add additional arguments to the function, and not only the result of the previous function:

function a(str) {
	return 'foo'+str;
}

function b(str, s) {
	return str+'bar'+s;
}

function c (str, s, a, b) {
	var w = 'baz';
	return w+str+w+s+(a+b);
}

Doing this traditionally would look like this:

alert(c(b(a('qux'),'lol'),'rofl',8,2));
//prints "bazfooquxbarlolbazrofl10 "

Holy crap, this is ugly! And you know it, we all write ugly and bad code from time to time.

I have upgraded the function to treat non function array elements as additional arguments to the function. So you can do this:

[a,'lol',b,'rofl',8,2,c].chain('qux');
//prints "bazfooquxbarlolbazrofl10 "

or

['qux',a,'lol',b,'rofl',8,2,c].chain();
//prints "bazfooquxbarlolbazrofl10 "

Any previous non function array element will be treated as an argument to the following function element. That means that unfortunately you won’t be able to pass functions as arguments using this snippet.

So if there is any of you who had the same issue and was bored to write this, here you go. Sharing is caring! :)

And for the end:

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s