FP-style conditional callbacks

The other day I was putting together a little UI to collect emails: an input and a button. So I wanted the email to be take in when the user clicks the button:

dom.events.add(submitButton, 'click', tryRegisteringEmail);

OK, but it’d also be neat if the user could just hit Enter. So I’d do something like this:

dom.events.add(textField, 'keypress', someSuggestiveHandlerName);

Yeah, but the keypress handler feels a bit out of line with the first, it’s like it’s at a different level of abstraction. And then I thought, so I need it to do the same thing as in case of the button click — tryRegisteringEmail — but only if the pressed key was Enter. Here is what came out:

dom.events.add(textField, 'keypress', ifPressedEnter(tryRegisteringEmail));

Looks neat! Let’s code it:

function ifPressedEnter(handler) {
  return function (event) {
    var ENTER_KEY = 13;
    var pressedKey = event.originalEvent.charCode;

    if (pressedKey === ENTER_KEY) {
      handler.call();
    }
  };
}

By the way, this ifPressedEnter function — because it accepts another function as its input, and its return value is another function — is called a “high-order” function in functional programming lingo.

This pattern came handy when I wanted to implement delegated event handling. There was a list of friends, and some of them have a “Remind” button. I thought I would be good to deletegate the clicks on those buttons to a single click handler on the list element. Here is what came out:

dom.events.add(friendsListElement, 'click', ifClickedRemindButton(sendRemindMessage));

and the ifClickedRemindButton function looked like this:

function ifClickedRemindButton(handler) {
	return function (event) {
		var element = event.target;

		if (isARemindButton(element)) {
				handler(element);
		}
	};
}

Another high-order function made my day a little bit better. :)