‫Welcome back.
‫So, in the final two lectures of the section,
‫let's go back to some more advanced features
‫of React Router,
‫and, in particular,
‫let's learn about how we can fetch and mutate data
‫without actually causing navigations,
‫so without moving to another page.
‫And, so let's now leave behind or create order form
‫and we also no longer need this user slice.
‫And, instead, now we will be back
‫to working on this order page.
‫So, the page that is already opened right here.
‫So, as I said in the beginning,
‫sometimes we need to fetch some data from another route,
‫so basically data that is not associated
‫with this current page right here,
‫but we want to do that
‫without causing a navigation sometimes.
‫So, for example, let's say that here in the order page,
‫we wanted to load the menu data again,
‫and we already wrote all the logic
‫for fetching exactly that data,
‫but it is associated to another route.
‫So, to the menu route and not to this one,
‫but still we want to use it here,
‫because there is no point in writing that logic again.
‫So, in other words, what we want to do
‫is to use the data from the menu route,
‫but without the user actually going there.
‫And, so, for that, we can use the useFetcher hook.
‫So, this hook will return something called a fetcher.
‫And, so let's use use fetcher,
‫and as always also included here,
‫let's move that at the very top,
‫and then let's immediately use this fetcher.
‫So, the idea here is to load the menu data,
‫so that we can then associate the ingredients
‫to each of the different pizzas.
‫So, let's actually load another order here.
‫So, again, this test order that we have here.
‫And, so what we want to do is to extend
‫each of these items here with their ingredients
‫and so we can get that data from the menu route.
‫So, what we want to do is,
‫right after this component mounts,
‫we want to fetch that menu data using our fetcher.
‫So, if we want to do this at component mount,
‫then let's again use our friend use effect.
‫So, we haven't touched this one in a long time,
‫but now here we need it,
‫because we want to fetch this data,
‫not on some event,
‫but really when the page first loads.
‫Alright, and so the way we use this fetcher
‫is simply by calling fetcher.load,
‫and then the name of the route,
‫and this is actually it.
‫So, this will then load the data,
‫and will store it basically in this fetcher object,
‫and then later we can retrieve the data from there
‫when we want.
‫And, actually, let's only fetch this data
‫if there is no data yet.
‫So, we can do if there is no fetcher.data.
‫Alright, and just like normal page navigations,
‫this fetcher can also be in different states.
‫So, just like here in our app layout,
‫remember that we can have, in the navigation,
‫the state of idle loading or submitting.
‫And, so here, with the fetcher, it's the same thing.
‫And, so by default, the state is idle.
‫And, so let's only start fetching this data
‫whenever the fetcher is in the idle state,
‫so when it's not already doing something equal to idle.
‫Alright, and here we need to include that fetcher
‫in the dependency array,
‫and beautiful.
‫So, with this, our data should already be fetching,
‫which we can probably see in the network tab here.
‫So, let's just reload the page here
‫and then filter for fetch requests.
‫We need even more space.
‫But, here, we only have that one,
‫but, well, nevermind.
‫I believe it should still have worked.
‫Maybe, it is somewhere else here,
‫but, yeah, let's see later.
‫Let's first try to actually access this data
‫and then see what happens.
‫And, indeed, why not immediately log it here to the console?
‫So, let's say fetcher.data,
‫and then here in the console,
‫well, we don't get anything,
‫try that again,
‫and still nothing.
‫So, maybe we should remove this condition here just to test
‫or actually the problem is right here.
‫So, this is fetcher.state.
‫So, just like this.
‫And, yeah, so now there is our menu data.
‫So, that was a silly bug.
‫Maybe, you have even caught this before me.
‫But, anyway, what we want to do now
‫is to pass this data into each of these order items.
‫Alright, so where actually is that?
‫Ah, right here.
‫So, we want to pass in basically now
‫only the array of ingredients.
‫So, let's check that.
‫So, each of them has this array of ingredients.
‫And, so that's what we want to pass in now
‫as the ingredients prop.
‫So, each of these items doesn't need to know
‫about the entire menu,
‫only the ingredients that are relevant for the item itself.
‫So, we access the entire data at fetcher.data.
‫And, then if that exists,
‫so, again, very helpful, optional training.
‫And, then let's find the menu item
‫that corresponds to this order item.
‫So, that should be easy,
‫because they share the same ID.
‫So, let's just say item.ID.
‫So, here they actually are called ID,
‫but, in the order, they are called pizza ID.
‫So, they need to be equal to the pizza ID.
‫Now, here, I cannot call this item,
‫but let's just say element,
‫because we are already calling each item in the card item.
‫So, the element ID from the menu
‫needs to be exactly the same as item.pizzaId.
‫Okay, so this then returns the entire object
‫that corresponds to the pizza.
‫And, then, from there,
‫let's just grab the ingredients array.
‫Okay, and then here in that component,
‫let's accept that,
‫and then actually we already have that prop here,
‫along with the is loading ingredients prop.
‫So, why not also define that here immediately?
‫So, this is loading,
‫is basically fetcher.state whenever it is equal to loading.
‫So, just like before, similar to this navigation.state
‫that can also be equal to loading.
‫Alright, and so here,
‫let's now then use these two
‫by adding a new paragraph here below this div.
‫And, let's style this, of course, a little bit
‫making the text small, capitalizing the letters,
‫making it italic,
‫and a bit lighter.
‫So, text-stone-500.
‫And, then here whenever we are loading the ingredients,
‫then let's just return here,
‫loading and otherwise,
‫let's return ingredients.join like this,
‫and let's give it a save,
‫and beautiful.
‫There is the data.
‫So, let's try that again.
‫We'll just copy it, then move here,
‫and, well, I'm glad we tested that,
‫because here we have some kind of bug.
‫So, probably, we are trying to read the data here
‫from fetcher before it even exists.
‫And, so let's just use optional chaining here on all of this
‫and then one of them should fix it.
‫So, let's just go back here, reload.
‫Try that again.
‫But, apparently, we have still some other error.
‫And, yeah, just here from this message,
‫we can see,
‫since we have the problem with the join
‫that the problem is apparently right here.
‫So, maybe this is loading ingredients is not doing its job.
‫Let's try to lock that here to the console.
‫Let's just reload here.
‫And, so then let's see if we get that lock.
‫And, so it is actually always false,
‫so let's see why that is.
‫But, apparently, here everything is correct,
‫so there should be no problem with this.
‫So, I'm guessing that the issue is that,
‫in the very beginning,
‫fetcher.state will be idle,
‫but that doesn't mean that we already have our ingredients,
‫so that we have our data already.
‫And, so in those very first instance,
‫here, we will not be loading the data,
‫but we also don't have the data yet.
‫And, so let's just try to return an empty array
‫then in this case.
‫So, basically, if this year doesn't exist,
‫then we just return an empty array.
‫So, that will then fix the problem
‫that here we are trying to join undefined.
‫And, actually, we can already see that this worked.
‫So, let's see that one more time.
‫And, so then it says loading.
‫And, after some time, you will see that data arrive.
‫So, here, then let's just add a bit of space between,
‫so space-Y-1, and nice.
‫So, with this, we finished yet another very small feature,
‫which wasn't even part of the requirement list,
‫but I still wanted you to show
‫this way of basically fetching data
‫without going to the page
‫where the data is actually coming from.
‫So, here, we are fetching the data from the menu route.
‫And, so we are making use of this loader function right here
‫to get the menu,
‫but, again, without navigating there.
‫And, so if you are using React Router
‫and all these data loading features,
‫in order to build a very interactive application,
‫you'll use this useFetcher hook here quite often,
‫which is why I thought that it was important
‫to also include that more advanced part
‫here at the end of this section.