In this video we're gonna take some time to explore callback functions in detail in this section.
Already I've probably said the word callback or callback function upwards of 20 times.
And now it's time for a dedicated video where we really dive deep into the callback pattern to see how
it works and how we can take advantage of it by creating our own.
Now why is this so important.
Because it's at the core of asynchronous no J.S. development.
It is something that's going to come up over and over again throughout the class.
And it's something that's worth investing in early on in our education.
So we're more comfortable with it as we continue to use it.
Let's go ahead and kick things off by moving into the playground directory for just this video.
I'm going to create a brand new file inside of here.
I already have one through three so I'll call this four hyphen callbacks dot J S and in here we're going
to explore callbacks in isolation.
Let's go ahead and start with an example we're already very comfortable with.
I'm going to call set time out like we've done plenty of times before passing in these two arguments
it requires.
The first is a function and the second is the amount of time to wait in milliseconds before that function
gets called.
And we're just going to wait two seconds and we'll print a message console dot log.
Two seconds are up.
Excellent.
In this three line example there is a single callback function and that is the function we define and
pass in as an argument to set time out.
So this is a callback function a callback function is nothing more than a function we provide as an
argument to another function with the intention of having it called later on.
So in this case we are providing a function as an argument to set time out with the intention that set
time out is going to call this function at some point in the future.
That is all a callback function.
It's now in this case we are using the callback pattern in an asynchronous way as we saw set time out
is a node provided API and it is indeed a synchronous.
Now that does not mean every time we use the callback pattern it's actually a synchronous.
This is a point of confusion for a lot of people.
We've actually already proven this.
We know that set time out uses the callback pattern and it's asynchronous and we know that our array
methods like for each and filter use the callback pattern but they are indeed synchronous.
So right here let's create a concept called short names.
Actually let's just call this one names will create short names in a second.
And I'm going to toss my name in there along with Jen and Jess.
And the goal is to use callbacks with filter something we've done before.
So const right here short names equals I'll access names dot filter to use the filter function and once
again we're going to provide a callback function.
I'm passing a function to another function with the intention of having it get called later.
So right here this callback function as we know will actually get called one time for each item in the
array with the individual item.
In this case we could call it something like name and all I'm going to do is return true if the name
has a length less than or equal to four.
Those are the short names we'll keep.
So return name dot length less than or equal to four.
In this case we are indeed using the callback pattern as well but there's nothing asynchronous about
filter it's not interacting with a native node API it is just standard javascript code completely synchronous.
So far the only time we've used the callback pattern is when we're working with a function that we never
defined.
So we pass a callback to set time out.
That is a node j s API and we passed a callback to filter also not defined by us.
That comes from javascript.
Now this is not to say it's never useful to define your own function that takes a callback because it
actually is and it's something that we're going to use in the very next video.
So let's take a quick look at app dot J.
Let's imagine in my program there are four different places where I want to be able to take a location
and get the coordinates back.
So I want to be able to geo code.
Now what is that going to look like.
Well if I have four or five different locations I need to do this.
I have to take this code and I have to put it in four or five different places.
And obviously that's not ideal.
So what we would do is we would create a function called GEO code or something like it and all of this
code would go inside of there.
Now in order to get that done we're gonna have to be pretty familiar with the callback pattern.
So let's go ahead and see what this would look like over inside of the callbacks playground file.
Let's create a constant.
And I'm going to call this constant geo code.
Now this is indeed going to be a function we define and we're going to set this function up to take
in a callback function much like set time out takes in a callback and much like filter takes in a callback.
Now you can take in as many arguments as you need along with the callback for example set time out takes
in the function as well as the amount of time to wait for geo code.
We could say that you need to provide the address.
Otherwise we don't know what address to geo code and we can say that you also need to provide a callback
which is the function that will end up calling once we have the data.
Now for the moment we're not actually going to do any geo coding inside of here.
We're just going to make up the results to keep things simple.
So for the moment let's create a concept called data and we'll just set up latitude and longitude properties
setting up random values for each.
So on data I'm gonna set up latitude as a property and I'll just set the value to zero.
Then we're also going to have our longitude and I'll set that to zero as well.
So let's say that at some point in the future yes we get this data back by calling request.
Now what do we do with it.
The goal is to give it back to the caller of geo code.
So if I call geo code and pass in an address like Philadelphia I want to get access to those coordinates.
Now we know there are two ways I could get this done.
One it could be the return value from the geo code.
Function like we've seen with pretty much every function so far.
Or we could provide a callback and get the data there.
Now if this was our actual function the choice would be easy.
I would ignore and remove that callback argument and I would just return the data then down below I
could access that data const data equals whatever comes back from Geo code and I could use it down below
console log data.
Perfect.
Let's go ahead and save the file in its current state and move over to the playground folder to run
things.
So that's gonna be C D dot dot forward slash playground to get over there once we're there I will clear
the terminal output and from here I'm gonna run the file so node 4 hyphen callbacks dot J.
S.
Now when I run it I'm going to expect to see my data showing up and it is and then two seconds later
I get my little message from the example up above.
The problem here is that there's nothing asynchronous happening inside of here.
Later on we're actually going to use request inside of here and we know that's a synchronous for the
moment as we explore the callback pattern.
Let's just use set time out to simulate this delay.
So I'm gonna take all of the code inside of the GEO code function.
I'm going to use command X or control X to cut it out copying it to the clipboard because we'll paste
it in in just a second from here.
I'm gonna use set time out to simulate a delay and let's go ahead and provide the function to run when
we're done and we'll provide the time to wait to keep things easy to see in the terminal.
I'm gonna pick a longer than average time.
I'm going to stick with two seconds though in reality this process would take just a fraction of a second.
Then I'm going to paste the old code exactly like we had it inside of these set timeout callback.
Now let's go ahead and run the program again to see what happens in the terminal.
I'm gonna use up and enter and we can see that right away.
Much shorter than two seconds we saw undefined printing.
So the problem here is that Geo code this function it's not returning anything.
Look at what's inside of this function.
There is a single call to set time out.
There is no return statement directly inside of geo code.
So geo code finishes almost immediately.
And if you don't return something from a function we know that JavaScript will implicitly return undefined.
So that is what we end up seeing.
Now yes there is a return statement in geo code but it is nested in another function so that return
statement is returning from this function not from this one which is why we're not getting a value back.
So the return pattern is no longer going to work for us when we start to do asynchronous things inside
of our functions.
And that's where the callback pattern is going to come into play.
So let's change our code to use callbacks and get it back to a working state.
The first thing we're going to do is remove the expectation we have right here that Geo code is going
to return some sort of useful value that's not going to happen.
Remember that when we explored how everything works behind the scenes none of our callback functions
the ones that go to no API then come down to the callback queue.
They don't get executed until the call stack is empty.
That means Maine has to finish right here we're trying to say that one of those callbacks should finish
before main finishes and that's never going to happen.
So we have to adjust what we're gonna do is we are going to remove data and remove our console log geo
code is not going to have a direct return value and that's ok it's expected what we're going to do from
here is provide that second argument.
The first one is address currently Philadelphia.
The other one is a callback which is just going to be a function.
So right here I am going to provide a function as the second argument.
Now you could have reversed the order or added as many or few arguments as you needed in this case 2
was the perfect amount for us.
Now this callback function is going to get fired at some point in time and the question is what things
are we gonna have access to.
Well that's up to us to choose.
So right here instead of returning the data we're gonna go ahead and call the callback function passing
the data in as that first argument.
So if we're calling the callback with data as the first argument that means we're calling this function
with data as the first argument.
So right here I can name that first argument so I could access it.
I'm gonna call data.
But I could call it anything.
I wanted to.
This name does not need to match up with this name.
It is the position that matters here it's the first argument down below it's the first argument and
now we can use it.
So console log data and now we're using the callback pattern in our little fictitious example.
So let's go ahead and run the program one more time.
Now we're going to wait those full two seconds as expected.
We then get access to the data we call the callback.
Our message prints and what are we seeing down below.
I am seeing my latitude and longitude showing up which is a great step in the right direction.
So if our function is completely synchronous like geo code was before we're able to use return to get
a value out of the function and back to the part of the code that called that function when our function
starts to do something asynchronous though that's no longer an option.
So instead of returning a value we take a call back in and we call the callback with the value we want
to send back when we have it.
This accomplishes the same goal as the return statement does.
It still gets the value back to the code that needs it.
Now that we have this in place it's time for a quick challenge where you're going to do something similar
creating a little function that uses the callback pattern.
Once we're done with that in the next video we're actually going to use the callback pattern inside
of app dot J S with our geo coding and our weather fetching functionality.
So to find the challenge for this one we can head over to a U R Well that's links dot Mead dot I O forward
slash callback.
This is going to redirect us over to another Github Gist and we're going to do is take all eleven lines
of code and we're going to bring them over to our four callbacks file.
Now before I paste them in I am going to highlight all other lines and comment those out.
So nothing else is running though I'll keep them in place as a reference for the future and down below.
I'm going to paste the challenge comments in and we'll notice that this challenge also comes with a
little bit of JavaScript code.
The goal here as stated is to mess around with the callback pattern like we did up above for geo code
and like we did for geo code.
We're gonna stick with a simple set time out call to simulate some sort of asynchronous process.
Now you're going to define an add function that accepts the correct arguments and the usage is actually
down below.
So add it takes in three arguments it takes in two numbers.
These are the numbers that get added up and it takes in a callback which is going to get called after
a two second delay with the sum.
Then the code prints the sum.
So your job is to get this code working.
Now what's step 1 defined the add function with the correct arguments as seen below.
Step 2.
Use set time out to simulate a two second delay after those two seconds are up.
Call the callback function with the sum.
That means you're calling this function with the correct sum.
Then you're going to test your work.
If your definition of the add function is correct when you run the program you should see the number
5.
Printing after 2 seconds.
All right take some time to define that function right here when you're done come back and click play.
How'd that go.
I'm gonna kick things off by creating a brand new variable cost add I'm gonna set that equal to a new
function and this function is gonna need to take in all three arguments.
We have two numbers and the callback so I could use something like a and b or X and Y then the callback
function which is typically called callback but it could be called anything you wanted to call it.
Next up we have to simulate an asynchronous process by using set time out to cause a two second delay.
So right here I'll pass in my callback function and two thousand milliseconds as the second argument.
That brings us to step 3 after those two seconds are up.
We want to call the callback function with the sum.
Remember I can't use return here because I'm returning from this inner function not from ADD.
So instead of using return I will call callback.
Now what am I calling it with a single argument the sum that's going to be a plus b.
Now maybe you created a sum variable first and past that in or maybe you added them up right inside
of the arguments list.
Either way would get the job done.
Now from here we can test our work.
I'm gonna save the callbacks file.
I'm gonna rerun things down below.
We wait are two seconds and what do we get.
We get the number five printing.
So now we have a bit of experience working with this callback pattern.
We've seen it used with set time now to simulate the asynchronous process and then the next video we're
actually going to use it with our request calls where we get that each TTP request data back.
Let's go ahead and wrap this one up by removing those challenge comments.
I'm gonna save this playground file and then the next video we're gonna move back into the weather app
directory.
I'm excited to integrate callbacks into our weather application.
So let's go ahead and jump right in to the next one.