‫Next up, we also need to clean up
‫our data fetching.
‫Because right now, we're actually creating way too many
‫HTTP requests as we search for movies.
‫And to show you what I mean by that,
‫let's make our window here a bit bigger.
‫Let's come to our network tab again.
‫Let's add some throttling here
‫and then make sure that you're here, in the fetch tab only.
‫Then let's clear all the requests that had been made before.
‫And then I will just very quickly search for a movie here.
‫All right.
‫And so here we can now see all the requests
‫that have been made.
‫So basically we see
‫that we made one request for each keystroke.
‫So it started here, then in or whatever, then incept
‫and all the way until the final word.
‫Now the problem with that is,
‫that this created all these different requests
‫that were basically happening at the same time.
‫And that has two problems.
‫First of all, having so many requests at the same time
‫will slow each of them down.
‫And second, this means that we will end up downloading
‫way too much data.
‫Because we're actually not even interested
‫in the data for all of these other queries.
‫But still, they were downloaded here.
‫Now in this case, it's very, very little data.
‫So that's not going to have any impact.
‫But in another application,
‫this might actually become a problem.
‫And so let's now learn how we can clean up,
‫basically our fetch requests,
‫so that, as soon as a new request is fired off,
‫the previous one will stop.
‫So it will get canceled.
‫And actually, I forgot to mention the third big problem
‫with having all of these requests
‫happening at the same time,
‫which is, imagine that actually, for example,
‫this request here would take a little bit longer
‫than the other ones.
‫So if this request here would be the last one to arrive,
‫let's say this one,
‫well here we then get the response if we click.
‫But anyway, again, let's imagine that this request,
‫for some reason, took a lot longer than all the other ones.
‫And so then this one would be the last one to arrive.
‫And so in that case, it would be the movies or the results
‫from this request that would be stored in our state
‫and that would be rendered in our UI.
‫Which is of course not what we want.
‫We always want exactly the last request of all
‫to be the one that matters, right?
‫So all these other ones, again,
‫we are not interested in them.
‫But if one of them takes longer than the rest,
‫then that one will actually become
‫the one that we see in our UI.
‫And this is actually a pretty common problem,
‫which even has the name of a race condition.
‫Because all these requests here are basically racing
‫with one another, seeing which one arrives first.
‫And so let's now fix that issue back in our code.
‫And the way that we will do this,
‫is by using a native browser API,
‫which is the abort controller.
‫And we will then use that abort controller
‫in our clean up function.
‫So the first step for using the abort controller,
‫is to actually create one.
‫So let's define a new variable, called controller.
‫And then we use, new abort controller.
‫And again, this is actually a browser API.
‫So this has nothing to do with React
‫but with the browser itself.
‫So just like the fetch function right here.
‫Okay.
‫Then here, in order to connect the abort controller
‫with the fetch function,
‫we pass in a second argument,
‫where we define an object with the signal property.
‫And so there we pass in controller.signal.
‫So it's not really important to understand exactly
‫how this abort controller works.
‫This is basically just following a recipe.
‫Okay.
‫So we have our abort controller
‫and we connected it with our fetch.
‫And so now in the cleanup function,
‫so a function that we return from here,
‫we can then actually
‫say controller.abort.
‫All right.
‫And that's actually it.
‫So let's see that this works in practice.
‫And then we will understand what is happening here.
‫And we will also do some minor fixes.
‫So let's make this big again, so we can see.
‫And reload the entire thing.
‫And immediately you see a small problem here.
‫But for now, let's ignore that.
‫And again, search for a movie.
‫Okay.
‫Now here we have a different types.
‫So we have this fetch and a fetch redirect, for some reason.
‫But we are only interested in the fetches here.
‫And immediately you see that all these other ones
‫which are not the last one, got canceled, right?
‫And so we can also see that now we no longer have
‫all these different requests happening at the same time.
‫So this one here started basically
‫and then immediately as the next one started,
‫this one was finished, so it was canceled.
‫This thing keeps popping up, makes it hard to explain.
‫And yeah, then finally,
‫the last one that we were actually interested in,
‫was of course not canceled.
‫So this one then went all the way until the end.
‫All right.
‫But here we can very clearly see
‫that there is basically only one request happening
‫at a time, until it then got canceled by the next one.
‫So let's just see why this is actually working.
‫So each time that there is a new keystroke here,
‫the component gets re-rendered, right.
‫And as we already know,
‫between each of these re-renders, this function here,
‫so the cleanup function, will get called.
‫And so what that means, is that each time
‫that there is a new keystroke, so a new re-render,
‫our controller will abort the current fetch request.
‫And so that is exactly what we want, right.
‫So we want to cancel the current request each time
‫that a new one comes in.
‫And so that is exactly the point in time
‫in which our cleanup function gets called.
‫And so again, the cleanup function is a perfect place
‫for doing this kind of work between renders.
‫Now the problem with this is,
‫that as soon as a request get canceled,
‫JavaScript actually sees that as an error.
‫And so that's why we then get the error here.
‫So basically this fetch request, as it is canceled,
‫it'll throw an error, which will then immediately go
‫here into our catch block, where the error is set.
‫And so that's why we can also see the errors down here.
‫So saying that the user aborted a request,
‫which is exactly what we have here.
‫However, this is not really an error
‫here in our application.
‫And so we want to ignore that.
‫So what we can do in order to do that
‫is to say, if error.name
‫is different from
‫abort error, only then we actually want to set the error.
‫And this works because the error that is thrown here,
‫so this object that we then get access to,
‫will have the name property set to abort error.
‫And then here we use that to our advantage, to again,
‫basically ignore these errors that are of this type.
‫And so only if they're not,
‫we set the error to the one that we are interested in.
‫Now to make this work here,
‫actually, we need to also set the error
‫to an empty string, after the movies have been set.
‫So we basically set the error to an empty string,
‫here at the beginning and at the end as well.
‫Okay.
‫And so let's try that now.
‫And we are still doing that throttling,
‫that's why it took so much time here.
‫But anyway, let's just again clean this here.
‫And, so now we never got that error
‫so we still got all our requests here, canceled.
‫And so, no more race conditions
‫and no more unnecessary data being fetched.
‫And so, if at some point in the future,
‫you are going to do your own HTP requests
‫in an effect like this, make sure to always clean up
‫after your fetch requests,
‫in case that you have a situation
‫where many requests can be fired off very rapidly,
‫one after another.
‫Which is exactly the situation that we have here.
‫So here, when we click on one of the movies
‫and the data gets fetched,
‫then usually we will not have so many requests
‫one after another.
‫Unless we click, like really fast
‫between these movies right here.
‫But that's usually not going to happen.
‫And so therefore, there's no need to clean up
‫the fetch that we're doing here
‫in this movie details component.