Okay, then. So far we're making this request and then we're reacting when we get some kind of data back or if there's an error. Now, it would be nice if we could wrap up all of this code inside a function called get to do's, for example, so that we could call this function whenever we want to run this code and make a request that makes it more reusable. So let's do that. First of all, come to the top and create a new constant. We'll call this get to do's that's the function name and set it equal to a new arrow function like so now inside this function, that's where we want to do all of this request stuff. So cut that and paste it inside here. Just scoot this in a little bit. All right then. So now we have all of this request stored inside a function. And if I want to run this code now, all I have to do is come down here and say, get to do's like so. So if I save this, then everything's still going to work the same way. But the good thing is now we're making this more reusable. So I could call this multiple times if I wanted to. Now I don't want to at the minute, but the option is there if I did now, at the minute, every time we call this to do's function, if I did call this multiple times, all we're doing each time is just logging the response to the console. Now, it would be nice if I could instead pass in a callback function to get to do's, which we then fire over here so we could specify how we want to react in that callback function. Then every time we call get to do's we could specify a different kind of callback function to do something different each time if we wanted to, instead of just always doing this inside the function. So that's what I'm going to show you how to do. The first thing we're going to do is specify a callback function in here as an argument to get to do's. So that will be just an empty arrow function at the minute. Now, obviously, since we're passing this through as an argument, we take it inside the function as a parameter. I'm just going to call this callback, but you can call it what you want. Now when we have either some kind of successful response or a bad response, we can, instead of logging this to the console, just call the callback. So I'm just going to say over here, instead of this callback like so, and I'm going to do exactly the same thing down here callback. Now, whenever it reaches ready state for this request and we get a status of 200, we call the callback. Or even if we don't get a status of 200 and we just reach ready state for we still do that callback. So this function right here is going to fire because we're invoking it over here and we pass it in up here. So let's just test this. I'm going to console dot log and I'm going to say callback fired. So save this and refresh. We can see now callback is fired. Now, the problem is, even if we have an error over here and save, we still just get callback fired. We see the error, but it's still firing this and we're getting the same kind of action even though we've got an error. And that's because all we're doing in both cases over here, even if it's a success, we have data we're calling callback. And when we don't have a success but it finishes the request, we're still just firing callback. Now, it would be nice instead if we could pass through the data here and the error here, so then we can check for that inside the callback down here. So what we're going to do is take in two parameters into this callback function. We're going to take in an error and we're going to take in data. Now, convention is when we do callbacks like this from a network request, we always do the error first, then the data second. That's just convention. So up here, what we could do is pass through some of these values. Now, obviously, in this case, if the status is 200, we don't have an error. And all we have is the response text the data. So for the first parameter right here, error and for the first argument up here to match it, we can pass through undefined because obviously the error in this case is going to be undefined. Now the second parameter is the response text. So let's say request dot response, text, and now we're passing the data through as the second parameter. Okay? So down here, instead of doing undefined for the first argument, we're going to say could not fetch data. So that is the error right here. So we're passing that through as the error argument or the error parameter here. Now the second one obviously is going to be undefined because in this case we don't have data because we don't have a status of 200. So now if we were to save this and run it, then we're calling the callback function slightly differently each time. If there's an error, we call it with this error and undefined for the data. If it's a success, then we're calling it with undefined for the error and this data. So let me just do this with a success, first of all, and what I'm going to do in each case down here is console dot log error and data. Now we're doing it to the correct endpoint first. So this should run so we can see if we scroll up now. That we now get callback fired. Then we get undefined for the error. And then this for the data. Now if we switch this up so that this is incorrect, save it. Now we get callback fired. This for the error could not fetch data and undefined for the data itself. Okay, so now what we could do in here is check if we have an error. Then do one thing. If we don't have an error, we can do another. So let's say if and then error like that. If there is an error, remember this string over here is going to be truthy. If there's not an error, this is going to be false. So this is only going to fire if we fire the callback function this way. So what I'm going to do right here is console log the error, and I'm going to do an else case right here and say console dot log data like that. So let's try this out. Currently, we should get the error right here because this is incorrect. Save it and we can see callback fired could not fetch data if we change this so it is correct like that and save it. Now we see we get the data and at the top it says callback fired. So this is all working. Now. We've made our code more reusable by putting it inside a get todos function. Then we can call that function to go and get the todos passing a callback function as an argument. We take that as a parameter and then we fire it down here with either the error or the data if it's a success or not. So that is a lot more reusable. And we could call get todos as many times as we want. So I could copy that and paste it down here. And each time around we could do something different in the callback function so it's more flexible. So I want to tie this into the whole idea of asynchronous code right now, because remember, that's what this chapter is all about, asynchronous code. And I said that asynchronous code is something that can start now and finish later. So let's put this into practice. I'm just going to say console dot log up here one and then I'm going to duplicate that. And in fact, I'm going to copy it and paste it down here a couple of times as well. We'll change this to two, this to three and this to four. So we'll save that. And now what should happen is this should fire. This should fire. Then this should start that's going to start the network request. It's going to pass this off to another part of the browser so that we can carry on with these statements in the queue and we'll carry on with console log three, then four. Then at the end we're going to fire this callback function when the data has come back to us and the rest of the statements have been fired. So this is not going to be blocking code. So if I save that, we can see over here. If I scroll to the top, we get one, two, three, four. Then at the end we get callback fired and the data, once the network request has completed, we're not having to wait over here for this to complete before we fire these two things. It's non-blocking code. It's asynchronous code, meaning it starts now and can finish later. So this whole idea of starting something right away, but finishing it later and letting the rest of the code run in the meantime is the beating heart of asynchronous behavior.