‫In this lecture, let's use our context
‫to finish implementing the city component.
‫So right now when we click on one of these cities
‫it takes us to the city component
‫but it doesn't have any data
‫about the city yet except for the ID.
‫And so let's now change that
‫and basically fetch the data for this city
‫and then show it in this component.
‫So basically what we want is this.
‫So it loads the data about the city and shows it here.
‫So what that means is that we do an HTTP request
‫to this URL /cities,
‫which remember gets all the cities,
‫but then if we take one of these IDs
‫that is automatically generated
‫and then paste that here,
‫then we get only the information
‫about this exact object right here.
‫Now, you might be wondering why we actually need
‫to do that if we could simply get this object
‫out of the array that we already have, right?
‫And that's actually true in this small application.
‫So technically we wouldn't have to create a new HTTP request
‫and fetch this data from the server again
‫because we do actually already have it in the cities array.
‫However, in real world web applications, it's quite common
‫that the single objects have a lot more data
‫than the entire collection.
‫So basically this array here
‫would only have a small amount of data in each object
‫while then the objects that we get individually
‫from the API have really all the data.
‫And so let's pretend that we really need to do this.
‫So making a request to this URL and then slash the ID.
‫So let's go to our cities or actually our city component.
‫And so let's fetch the data here
‫because this is where we need the data.
‫So let's remove this.
‫And what we could do is now to create that HTTP request
‫and then create some local state here
‫and call it for example, current city
‫and set current city and then use state
‫and then store whatever the object is here
‫into this state, right?
‫So that would be a perfectly valid way of doing it.
‫However, that state would then of course be local state.
‫So it would be local
‫to only this component right here.
‫However, we do actually need the state in another place.
‫So to implement another feature that I'm gonna show you now.
‫So watch what happens when I go back from Lisbon.
‫So you see that then Lisbon here
‫is marked with this green border,
‫which means that this is now the current city still.
‫So basically after we visited one of these cities
‫when we then go back
‫it marks the last visited city with this border,
‫which means that this city item component here
‫also uses this same piece of state.
‫So what this means is
‫that this state is actually global state
‫because multiple components in the tree need this state
‫and therefore it is a good idea
‫to actually place this not here,
‫but inside our context.
‫So next close to these ones.
‫Now, okay, now again
‫if we only needed this state here in one single component
‫it would be best to use local state in that case.
‫However, we do need the state variable
‫in multiple places.
‫And so therefore we will place it here
‫into the city's provider and then paste it into the context.
‫And let's do that right now immediately.
‫So current city.
‫And so now all we need to do is to create a function here
‫that loads this city, which we can then call right here
‫as the component mounts.
‫So that sounds a bit confusing.
‫So let's just do that.
‫So let's just create a function called get city
‫which will just receive the city ID.
‫And then the logic itself is actually pretty similar
‫to this function that we already have here.
‫So I'll just copy this and place this here.
‫And then here, remember that we now need to attach
‫the ID to this URL.
‫And so that's why we paste it into this function.
‫So ID here and then of course the data that we receive
‫is placed into current city.
‫So set current city and that's actually it.
‫Well, actually this should not be here.
‫And then yeah, this of course is also an async function.
‫Now right,
‫now we could also have placed this function right here,
‫so into this component
‫and then call it here as the component mounts.
‫But I think it's a bit cleaner
‫to have all these functions
‫in the central place inside the context.
‫So here inside this city's provider.
‫So later on we will also have more functions
‫to create a new city and to delete a city.
‫And so we will then have all these functions here
‫in the central place.
‫Then all we have to do is to paste that here
‫also down into the context.
‫So get city
‫and now inside this component we can get the city
‫and then display it.
‫So this ID of course we still need
‫because now we need that to actually fetch the data.
‫But anyway, let's now then get the get city function
‫from use cities now, right?
‫And of course we will then also need the current city
‫and no longer this temporary one.
‫And so then we can very easily do an effect like this
‫where we simply call the get city function
‫that we just got access to with the current ID
‫which is coming remember from the URL.
‫And so we want to run this function
‫or this effect as the component mounts.
‫Now here React is complaining about
‫some missing dependencies in the dependency array.
‫So that's get city and ID, so let's add ID here.
‫But the get city function
‫that React also wants we will actually not add for now.
‫So even though we are required to add
‫all the dependencies to the dependency array,
‫now we will just remove this here
‫and we'll come back to this in the next section.
‫So by then I will explain you
‫why we couldn't add this
‫to the dependency array at this point.
‫So we just add the ID,
‫which is actually important because the ID might change.
‫And so then in that case,
‫the city corresponding to that new ID would be loaded.
‫Now, okay, now let's get rid of this code here also of this.
‫And so now we want our actual JSX
‫that will nicely render the city.
‫So let's give it a save, then we have no more errors
‫and everything's looking good.
‫So let's try this out.
‫And we actually already see Lisbon there,
‫but let's give ourselves a bit more space.
‫Let's come back here and reload.
‫And then I will again click on Lisbon.
‫And there it is.
‫Beautiful.
‫So all logic here worked.
‫Let's try another one, Madrid.
‫And you saw that first it shortly displayed Lisbon
‫and only then as soon as the the Madrid data arrived
‫it then switched to this new state.
‫So let's fix that soon.
‫But for now, let's really understand what happens here.
‫So let's start from the beginning.
‫So when we click here on this link here the URL will change.
‫So we get a new ID
‫which we then read here into the city component.
‫So then we have this ID
‫and we use it to call the get city function
‫as the component mounts.
‫So immediately after mounting,
‫we start calling this function
‫which is coming from our context, remember?
‫So here we have the get city function,
‫which will then immediately start fetching
‫the city data for that ID.
‫Then when that arrives
‫it gets stored here into the set current city state.
‫So this state variable right here,
‫which we also paste into the context value.
‫And so then immediately here
‫this city component receives that value as it updates.
‫And then well here we de-structure it
‫and then display everything in the UI.
‫So basically here we do child to parent communication.
‫So we call this function here
‫which will then update the current city
‫and then the current city will come back down here
‫into this component where we can then use it.
‫But now about this issue that we saw earlier.
‫So if I click here now
‫then it will shortly still show Lisbon, right?
‫So saw that for half a second
‫it still showed us the current city.
‫And the reason for that is very simple.
‫It's because that was the earlier current city,
‫so the one from before.
‫And so know where we are resetting that
‫and actually we don't want to reset.
‫So because remember we want to then
‫use the current city to display this green border.
‫But what we want to do instead is to
‫show a loading spinner here.
‫So let's also get the is loading state
‫and then depending on that we want to display the spinner.
‫So where do you think we should do that?
‫Right here, maybe.
‫Well, let's try and then you will see what happens.
‫So if it's loading, then return the spinner.
‫Let's see if we already have it included.
‫No, we don't.
‫But now it is.
‫But as I save this here, we get this ES linked error.
‫And so the reason for that is because we violated
‫the very important rule of hooks,
‫which says that hooks always need to be called
‫in the same order.
‫So by having this return here before this hook,
‫this one here might never actually be created.
‫And so that's a problem.
‫So let's do that maybe here
‫or well, let's do it really close to the other return.
‫And so now watch what happens.
‫Yeah, nice.
‫Then we get the loading spinner and then our city.
‫And now let's implement that feature,
‫which shows us which is the current city.
‫So again, that's just this green border right here.
‫So that is right in the city item.
‫So right here
‫and basically we have a special class for the active city.
‫So that's this class right here.
‫So let's just copy that.
‫And so here we want to now conditionally apply that.
‫So, remember that if we want to add multiple class names
‫with CSS modules, we need to do so in a string.
‫So let's create a template literal.
‫So this one we want for sure,
‫but now we need to conditionally add that class.
‫So in which situation do we actually want to add that class?
‫So when is a city active?
‫Well, it is the active or actually the current city
‫when the city ID is equal to the current city ID.
‫So to this one here, right?
‫And so we now need to read that current city
‫here into this component.
‫So current city,
‫which we get from use cities, that's right.
‫Now, okay.
‫And now here we can do our conditional.
‫So if the ID is equal to currentCity.id
‫then here we want styles.
‫And now we cannot do this.
‫So this doesn't work because of the dashes in the name.
‫And so instead, we need to do this, alright?
‫And otherwise don't place any other class there.
‫And we see immediately that it works.
‫So let's try that with Lisbon.
‫Go back and nice.
‫So now that is the current city.
‫Here we have some errors.
‫Yeah, so that's nothing meaningful.
‫What matters is that the feature now works.
‫And now finally, notice how we always have to
‫click here on cities in order to go back.
‫So actually what we want here is a button
‫that allows us to go back.
‫So similar to the button that we have
‫when we click here to show the form, remember that.
‫So as I click here, it opens this form.
‫And so here we have this back button.
‫And so now we want exactly the same in the city component.
‫So let's come to the form.
‫And so what we want is this button
‫plus this functionality here.
‫So should we now just copy and paste this button?
‫Well, actually no.
‫I think it would be a good idea to now make a component
‫for this button because we clearly need to reuse this.
‫And so this is a great candidate to extract
‫into a new component.
‫So let me just copy it actually.
‫So I will remove it later.
‫And then let's call this one the back button.
‫So then our snippet here as always.
‫And now what we want to return from here is this button,
‫but this button actually depends on a few things.
‫So for example, this navigate function right here.
‫So let's cut that, place that here.
‫But then of course we are missing the import.
‫So let's also grab that from here.
‫And maybe we can actually remove this from here for now
‫because then we will want to import it, of course.
‫Now okay, and now we just need to import the button.
‫So let me just remove a piece of this here and nice.
‫There it is.
‫So I think this should be complete.
‫Let's close this and then let's import that here.
‫So the back button, which somehow doesn't work.
‫So the import, so let's just do that manually here.
‫So back button and nice, there is our button back.
‫And now if we go to the city
‫and then one of these cities here, let's go there.
‫We can close all of this.
‫And so let's inside this diff here, add that back button.
‫And there it is.
‫Let's see.
‫And indeed it does go back.
‫Great.
‫So this was a long lecture
‫where we did a lot of different things.
‫And so please make sure to review
‫everything that we did here.
‫Just clean up this.
‫And so then with this, we are actually finished
‫and can move on to the next topic,
‫which will be to finally add the actual map
‫here to this container.