Day 52 + 53 – Callbacks, Closures and Node as a Server

On Day 52 (Tuesday of MEAN week 1), I took a day off to take my wife to the DMV for her driver’s license (She never learned in China so she just started when we came to the states). In an attempt to avoid her having to parallel park on the test, we drove way up into the northern suburbs. Apparently, everyone else had the same idea that day because it was totally packed… We got there right at opening time, and we were still there for over five hours… I was able to do some reading on the platform at DMV, luckily, but it was not the most distraction-free setting and progress was slow until I got home in the afternoon.

Oh, and she didn’t pass the test… It turned out driving way out into the suburbs wasn’t a great idea after all because there were barely any cars and lots of weird shaped roads, and she ended up driving on the wrong side of the road at some point because the area was so unfamiliar. Oh well, there’s always next time. It was just a bit of a bummer after having to wait for five hours in the crowded DMV.

Anyways, the topics on the platform for day 52-53 were about more advanced JavaScript concepts. It’s been a while now and they don’t really seem as “advanced” anymore, but they’re definitely super important. The two biggest things we needed to learn before getting deeper into mean were Callbacks and Closures.

Callbacks

A callback in the simplest terms is just a function passed into another function. Callbacks are a pretty big thing in JavaScript and the MEAN stack, and now that I’m aware of them it feels like I couldn’t even survive without them! The most common example of callback usage is in any AJAX function. Let’s take a look at a quick example using jQuery:

1  $('#some-awesome-button').on('click', function(){
2    $.get({
3      url:'/awesome_url_to_get_some_partial',
4      success:function(response){
5        $('#some-awesome-div').html(response)
6      }
7    })
8  })

This is a typical example of a simple AJAX operation. We are binding a click handler to a button with the id, some-awesome-button, that will execute a GET request to the url, /awesome_url_to_get_some_partial, and replace the inner HTML of the div, some-awesome-div, with the response (which we’re assuming is some HTML partial). So where’s the callback? Well, if you take a look at line 4, where we are assigning the value of the ‘success’ key in the request object, you’ll see that the value we’re assigning is a function. That function is a callback! Whenever we define any AJAX function, we always need a success function to handle the asynchronous response. It’s like we’re saying, “hey, go make a request to this url, and then when you get the response, call back this other function here and pass in the response.” And that’s why they’re called callbacks (maybe. I dunno, I didn’t come up with the name, lol). So, to help this sink in, let’s separate out the callback we just pointed out:

1  var successCallback = function(response){
2    $('#some-awesome-div').html(response)
3  }
4  
5  $('#some-awesome-button').on('click', function(){
6    $.get({
7      url:'/awesome_url_to_get_some_partial',
8      success:successCallback
9    })
10 })

Here on line 1 we’ve got a function assigned to a variable, successCallback. Then, on line 8, we’re passing it into our AJAX call as the success function. Nothing too complicated, right? Callbacks are a piece of cake! Now that we’ve separated out our success callback, can you see any more callbacks in this example? *ahem* line 5 *ahem*

Closures

So callbacks are easy, right? After learning more about them on the platform at the beginning of the MEAN stack, I was kinda like, “Oh, that’s it? I’ve been using callbacks all along!” Especially in jQuery, callbacks are everywhere! (It is JavaScript after all) But closures are a different story. Even now I’m still a bit shaky when it comes to knowing when and why to use closures, but I think I understand what they are decently enough.

Basically, a closure is what you get when you put a function inside of another function. Why might we want to do this you ask? Well, I think it’s mostly because of how scope works (I might need to do another separate post on scope later). Remember how whenever you define a function and create local variables inside that function, those variables are only available inside that function? If you try to access some variable in function A from within some other function B, you’ll get an error because as far as function B is concerned, any variable inside function A doesn’t exist. BUT, what if you put function B inside function A? Well, since functions do have access to their outer scopes, and function B‘s outer scope is now the same as function A‘s inner scope, function B CAN access variables inside function A.

Wait… what? That probably sounds hella confusing and I probably repeated ‘function’ way too many times, so let’s just take a look at an example to see closures in action:

1  function makeGreeting(){
2    var greeting = "Hello, ";
3    function greet(somePerson){
4      console.log(greeting + somePerson);
5    }
6    return greet;
7  }
8  var greetingClosure = makeGreeting()  // this is our closure!
9  greetingClosure("Brodawg")  // should log "Hello, Brodawg"
10 greet("Broseph")  // should raise an error! greet is only inside makeGreeting!

In the example above, we have a very simple closure. The function defined on line 1 returns the greet function defined within its own scope on line 3. Because greet() is inside makeGreeting()‘s scope, it has access to the variable greeting. The cool part is that when the inner function is returned and assigned to a variable, it still has access to whatever was in the outer scope at the time of its definition. So, when we run invoke our function on line 9, we’re console logging a variable that we normally wouldn’t have access to. However, this example isn’t really showing the true potential of closures, so let’s change it up a bit.

1  function makeGreeting(greeting){
2    function greet(somePerson){
3      console.log(greeting + somePerson);
4    }
5    return greet;
6  }
7  var normalGreeting = makeGreeting("Hello, ")    // a closure...
8  var coolGreeting = makeGreeting("Sup, ")        // another closure...
9  var klingonGreeting = makeGreeting("nuqneH, ")  // another closure!
10 normalGreeting("Brosepher")  // "Hello, Brosepher"
11 coolGreeting("Broshizzle")   // "Sup, Broshizzle"
12 kligonGreeting("Brossolini") // "nuqneH, Brossolini"

Now we can start to see what the whole point of a closure is. The only change I made to our makeGreeting() function was to make it so our greeting is passed in instead of hardcoding it to hold the string "Hello, ". Thus, when we call makeGreeting(), we can customize the value of our greeting variable. Then I made three new closures on lines 7-9. Each closure is still referring to the same greet() function, but now each one has been defined with a different scope! It’s kinda hard to think of real world examples off the top of my head still, but hopefully these helped clear the subject up a bit. Closures are definitely a powerful tool to have in your toolbox!

This post turned out longer than expected, so I won’t go into much detail about Node as a server. Basically, we learned how to set up a basic server with node alone, which was pretty impractical because we had to define every possible route and use the file system module (fs) to go and find files and serve them. We never had to do it again because Express does all that tedious stuff for us, but I guess it’s kinda cool to see what it’s doing behind the scenes. I think the most important thing in the Node section of the platform was about how to use modules. (Later on, since I didn’t really have the time to learn webpack yet, I modularized all my front-end scripts with browserify, which works pretty nicely.) Maybe I’ll do a separate post on modularization later. JavaScript can definitely get ugly at times, but it doesn’t have to be!

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