An Itsy-Bitsy, Teeny-Weeny, Yellow Polka Dot … EventEmitter!

I recently attended the M’s workshop on functional programming, in which I learned that I needed HELP. (M is a fantastic facilitator at Hacker School. Here is the link to the blog post she wrote about said functional programming workshop.) I knew my client-side code was a mess, but I was clueless as to why exactly it was so stinky and at a total loss about how to fix it. Her workshop simplified the concepts behind functional programming, and made it approachable, and (more importantly), applicable. I’m writing this post as a summary of what I learned and how I’ve recently started applying it.

First off, here are some of the tips and tricks I took away from this afternoon of functional programming examples:

Declare It!

Write DECLARATIVE code, not IMPERATIVE code. Her example was writing a function called “make-me-a-sandwich” versus writing some code that is a tedious list of the steps necessary make a sandwich. In examining my recent code in this light, I found it full of tiny instructions that give the reader no overall sense of where it’s going and why. Plenty of room to chunk that shit up into declarative functions!

Avoid Mutating

Write functions that RETURN stuff without mutating what they are given. Functional functions take some parameters (say an array or string or object), use what’s within them (no referencing outside [especially not GLOBAL!] variables), and neatly return a modified COPY of what they were given. This is great, as you never end up writing over something you needed or modifying an outside variable unintentionally. Also, if you constantly return a clean copy of your starting data, it’s far easier to chain series of small tasks together, which makes it clear to the reader what you are doing with your code.

Quit Iterating with For Loops

I.E. Use MAP, REDUCE, and FILTER. These functions are great! I had little experience using them, but they save you a bunch of hassle and make it very clear to the reader what you are doing and why. M’s great example of all the unrelated crap people throw into a for loop made me laugh at myself out loud (new acronym: LAMOL?). I do that all the time! I used to think I was being efficient, getting more done in one loop. But it’s far cleaner to map my change onto my array of items, and it returns me a new, safe copy. I have questions about the potential Big O sacrifice in mapping over my data many times instead of doing a bunch of crap in a for loop all at once, but for my general purposes (handling a very small amount of data — generally loops under 20 items), the benefit in clarity certainly outweighs the loss in performance.

Applying My New Knowledge to My Own Code

As always, much harder than expected. After M’s workshop I knew vaguely what had to be done, but in my client-side code, I have functions that handle JSON requests and responses, and functions that handle resultant DOM manipulation, and they must work together so intricately that I found myself with a mess of delicately interwoven spaghetti code. Appetizing, sure, but not pleasant to pick apart, and definitely not easy to make changes to.

After puzzling at the mess for an afternoon and evening, I sought M’s advice. She recommended implementing my own tiny client-side Event Emitting system so that my server-communication code could alert my DOM-manipulation code to changes without being dangerously interlaced. “Brilliant!” I thought. “Terrifying,” I thought. Implement my own Event Listener and Emitter?!? Are you crazy? Luckily, M showed me some example code, and demystified such a seemingly complex idea significantly. So, drumroll please, here it is in the flesh, my Itsy-Bitsy, Teeny-Weeny, Yellow Polka Dot Event Emitter:

var EventEmitter = function () {
    this.handlers = {}; 
    // we need to keep track of what actions (functions) are mapped to which named events
};

EventEmitter.prototype = {
    bind : function (event, fxn) { 
    // this is how we add "listeners" to certain events
	this.handlers[event] = this.handlers[event] || []; 
        // make sure we have an array in our handler, mapped to our event, to push our function into
	this.handlers[event].push(fxn); 
        // add our function to our event's array of functions
    },
    emit : function (event, data) {
	if (this.handlers[event] !== []) { 
        // if this event has listeners bound to it
	    this.handlers[event].forEach(function(fxn) { 
            // for each of our functions mapped to our event
		fxn(data); 
                // do the function on the data we emitted
	    }, data); 
            // forEach takes the parameter to pass the inner functions last
	}
    }
};

var sayMessage = function (message) { 
// let's define a test function that takes a piece of data
    alert(message);
};

var emitter = new EventEmitter(); 
// instantiate a new EventEmitter

emitter.bind('open', sayMessage); 
// bind the sayMessage function to the event called "open". 
// this gets stored in our emitter's "handler" map.

emitter.emit('open','banana'); 
// let's emit an event called "open" with the data, "banana", and see what happens:

// => if you put all this in a window.onload() function and load it in your browser, it will alert "banana"!

Okay, so what’s cool about this, and how does it relate to functional programming? First off, it’s cool because now my server-message sending and delivering code can be completely separated from my DOM-manipulation code. This is important. These two chunks of code deal with completely different things, and we want to keep them in their own zones. Then we can make changes within them without worrying about fudging up the other. (For the non-technical, DOM stands for Document Object Model, which is some garbage way of saying my HTML or the text-y output and physical elements on my webpage that the user sees, in opposition to the pure data that is transferred to and from the server.)

Anyway, what was exciting about writing this bit of code was the function forEach(). I had not used that before, and my (NEW) instinct was to try to map my array of functions to my bit of data (though usually map works the other way — mapping a function to an array of data…). Thankfully, M recommended forEach(). Upon researching forEach(), I found that it takes this second argument, which the documentation defines as “the object to use as this when executing callback.”

What’s exciting is that several weeks ago I doubt I would have understood that. Now, and especially after talking about closures in the functional programming workshop, I understand much better: that parameter is defining the runtime object or data that the function(s) you are calling within your forEach loop will be applied to. This is what allows us to “emit” an event and include with it some data that is (not magically!) passed to the function(s) that are mapped to that event in our handler map. Those functions, thanks to forEach(), are able to access that data we passed with our event emission. In my example, it means my event emission code can attach whatever it wants, and through the map inside my event emitter and the forEach execution, my bound function (in this case called sayMessage) can access the data I want to give it (in this case “banana”). Amazing!

One thought on “An Itsy-Bitsy, Teeny-Weeny, Yellow Polka Dot … EventEmitter!

  1. Peter

    Nice writeup! In the emit might you benefit from emitting the event too, so the function could potentially do something different for different events?

    fxn(evt, data);

    With jQuery events I sometimes i’ll have my callbacks do something different depending on which event triggered it.

    You could also get fancy and set what `this` is inside your callback functions by using the `call` method, e.g.,

    fxn.call(evt, data)

    If you do that, then it’s like doing `fxn(data)`, but inside the function, `this` is equal to the event.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *