Next lesson playing in 5 seconds

  • Overview
  • Transcript

2.4 Callbacks, the Other Higher-Order Function

You may have heard of callbacks before. There's nothing magical about them: they're just functions that are passed as arguments to another function, which is the other type of higher-order function. We use callbacks here to create an even more flexible filter.

2.4 Callbacks, the Other Higher-Order Function

So we've taken a look at higher order functions in the last video and we made this function here called makefilter. And so that took just a regular property value and then it returned a function, and so it's higher order, because it's actually returning another function. The other way we can build higher order function is to actually pass in our own function to be run. And this is most often called a call back. So if you've heard call back before we're gonna talk about what that is and how it works, and we're gonna do that by changing our filterBeers function. We said before that we're running into this problem where property and value, you know, what these are may have to change cuz we wanna be flexible, like if you wanna check two different properties. Or if you just wanna check the existence of different values on one property or against multiple. There's all, all kinds of mixups and mashups that you could do with filtering. And you wanna be able to be flexible to do that and not have really long comparison functions. Where you say, all right, if properties in array do this and if values in array do, it gets really out of hand. And so we're gonna actually implement a call back where you can define your comparison logic, your self and then the filtering just does the filtering against your comparison. So, instead of property and value, we're actually just going to take a call back. Now there's nothing special or magical about a call back. I wanna stress that, it is literally just a function that we are going to run on your behalf when you run filterBeers. So when you pass a call back to something, you're just saying here's a function that I want you to run later. Okay, so we accept that call back here. We still make our filter beers array, we still loop over the beers, but instead of doing this if statement where we do our compare values, we're actually going to just run the call back. And we'll just run it with the current beer. And so everything else stays the same. We're just off loading the comparison logic to you, so that you can run it yourself. And this is gonna break our makeFilter function, so we're gonna have to do a little bit of a fix there. Now, instead of passing the prop, the property in the value. We'll pass a function. We know that when our callback gets run, it's gonna be given a beer. So we can say beer here, and in here, we'll return and we're gonna do this simple comparison here. All right, so beer[property], wanna know if that is equal to the value. And so we're still using our cached scope variables, using the higher order functions from the last video. But now, we're actually going to have access to a beer, so we're going to pass this callback to our filter. And that will run, and that will do everything compare values was doing on the simplest path here. We'll still have to account for this path later and I'll show you how to do that in a minute. So just for now, let's comment out compareValues, cuz we're not using it anymore, so we'll just prove that. And then all these things can stay the same, I'm gonna save this and let's go look at our website. Okay, so refresh here. We've got all of our beers. The domestic filter still works, imports, stouts, lagers. But ales is gonna break, because we haven't we, we lost the reference to our check to see if that type is an array. And so, when that goes into that filter function, it just fails. So how do we fix this? Instead of putting all of that comparison logic in one function, and trying to account for every possible scenario in that one comparison function, instead now, we can just say okay, for this filter by type, instead of using our saved function, filter by type only filters by one type. We are going just use our filterBeers function directly here. Remember this takes a call back, so center function here, which gets a reference to a beer. And now we just want return if, oops sorry we don't need the if, just return. Does beer.type equal ale or beer.type equals ipn. So now, remember, this is looking more like it used to look and so I'm kinda going back and forth. But the point here is in the simplest case, where we're repeating things, it's the same exact thing. I just wanna, I just wanna compare a locale to a value, a locale to a value. Now in those cases, I can just make a simple filter. Create that as its own function and run it multiple times. It's nice, it's descriptive, it's declarative. Same with these types, where I'm just comparing against one type, same idea. But, when I have a special case, I don't have to destroy everything. I have a flexible system. So, I just call my filter beers function directly. I pass in the call back to do the comparison, which is a special case of comparison and in here, I could do anything. I could say, do I want to know if the starts with something, or the beer.type, and you can do and, right? We're not locked down to only or comparisons, or only one property. We can do any comparison that's on that beer object that we want. And so they were really, really flexible. So we save that and go back, refresh, hit all, domestic and import still works but now ales also filters the way we want it to. So this is now cleaned up, it's declared up, it's descriptive, it's functional, and it also gives us a nice flexibility to do any kind of comparison we want. And so, in the next video, we're going to go back to something I mentioned a while ago, and we'll talk about what a pure function is, and whether a function should have side effects.

Back to the top