Transcripts
1. Intro: You might have heard of API's, but do you know how to use them? Today, we're going to walk through everything
you need to know to build your own web
app using free API's. Hi, my name is Zoe. I'm a software engineer
and former professor who loves educating others on how
to get started with coding. I've created tons
of websites and web apps using React CSS, HTML. Next S and more. Today we'll be utilizing the free Rest Country's API in order to make this
country search web app. This project will
allow us to learn how to use next S and react, how to interact with
and incorporate API's into our projects. And how to use Javascript
or Typescript to succinctly filter and return
the requested data based on a user's query. We'll start with a
basic overview of what API's are and
why we're using next. Yes. And then we'll dive
right into our tutorial. The tutorial will be broken
up into three distinct parts. First, we'll style the web app, then we'll hook
it up to the API. And finally, we'll
refine the query logic to ensure that users are getting exactly what
they're looking for. This course is for
anyone who's interested in learning how to work
with an API in a web app. By the end of this course, you'll be able to do this all for yourself. Let's get started.
2. Class Project: Class project. The project
for this class is to build a fully functioning
country search web app using a free API. For this, you'll need
access to a computer and a code editor like
visual studio code. You should also have some
understanding of Javascript or type script as well
as HTML and CSS. To spin up our app,
we're going to be using a framework called Next
S, which uses React. We'll also be using material I for some basic
styling components. I'll leave links to any
assets and resources you'll need in the Project and
Resources tab right below.
3. APIs & Databases: Api's and databases. An API or an application
programming interface is a set of rules that allow front
end developers to create, read, update, and delete
data on the back end, these APIs are created by backend developers using
languages such as Python, Ruby, Java Script, and others. Databases, on the other hand, are where the data lives and are accessed via these API's. Depending on which
type of API request is sent from the front end, either create, read, update, or delete, a different set
of data will be returned. For instance, if a new
user goes to set up an account by typing in their E mail address and password. Once they hit Submit, that
information will be sent to the database and a new
user will be created.
4. Next.js: Next S. In the years that
have passed since reacts first introduced many frameworks have been built and
developed off of it. A very popular
framework today is Next S. Next S provides a lot of out of the box optimization such as servi side rendering
routing and improved SEO. And as such, it's a favorite
to front end developers. We'll be using it
in our project, so let's dive in
and get started.
5. Project Setup: Let's start working
on this project. The app that we're looking to build is something like this. It's a country
search app that when you type in the
name of a country, you can actually get
the result for it. You should also be able to just go ahead and
filter by region. So somewhere that's
in Africa or in the Americas or in Europe,
et cetera, et cetera. And also, I should say you can also switch it
into dark modes. You can turn on dark
mode or light mode. And so, yeah, we're going to
build out this app by using this free Country's Rest
API that is provided here. So as you can see, we have a
Country Rest API that allows us to hit this endpoint and then receive a bunch
of different details. So we can get the
name, the flags. There's a lot of
different information. So I'll leave a link
to this website in the Projects and
Resources tab below, so that you can follow along and use this in your project. And also the inspiration
for this project and the design for it actually comes from this website called
Front End Mentor. That's where I
actually get a lot of my projects to work on and
build projects out of, if you want to check
it out, front end, or it's a totally
free project to use, but you can grab
the design here and we're going to be working off of this image here to
build out our project. Yeah, let's go ahead
and get started. I'm going to get
started, as I mentioned, we're going to be
using next JS material UI and type script. I actually have built
a template that we're going to use to actually
work on our project. Here, I'm going to go ahead and get a repository started
using this template. Awesome. Now the
repository is created. You can actually, we can use it locally to develop
our country search app. And I'll also leave a link
to both the template and the repository that I
use for this that you can use that to start
as a starting point. And you can also check your
work as you're going along if you want to see what the final project ended up looking like. All right, so I'm going to
go ahead and clone this. Awesome. And then I'm just going to go ahead
and open it up. Perfect. So the next
thing we have to do, like whenever we clone a project
is we have to installed. So let's do a quick NPM install. All right, cool. So
it's installed now. We should just be able
to do MPM run dev. Awesome. And it's start at local
host 3,000 and great, we have our app up and
running so we're good to go. Let's go ahead and get started.
6. Styling the App: In this section,
we're going to be focusing mostly on the styling. So if you're more
interested in the logic, you could skip ahead
to the next lesson. All right, first
thing I want to do as usual is create a new
folder for my components. Then I want to go ahead and
clear out this next GS page. So I'm just going to
clear out everything in the main section
here, save that. I'm also going to
remove the styles on the di here, this
country search. That should be good for now when we're looking at
this example project. Right? We have a couple
of different sections that we're working with, right? There's like this
header section, there's this input section, there's a region filter here, a select, I see it as like
a few distinct sections. There's the header and
then there's this larger, the actual country piece itself. Then there's the display of
all these different cards. Let's break it into pieces. What we're going
to do here, first, I'm going to create a
container for the whole thing. I'm going to call it the
Country search container. That's just going to house everything that
we're working on. Cool. And we'll use Emmett
and then we'll just import this here.
All right? Perfect. If we check out this the front, we see we have our country
search container there. Perfect. This is going to hold a couple of
different things. Let's create another
component called header. Let's create another
component called, um, we'll call this
one Country Search. Okay, and we'll import both of these into
Country Search container. I'm just gonna change this to a box because that's like the, the material you by
way of doing it. And that would just
allow us to use different props using X, X, if you haven't
heard of it before. The prop SX basically
allows you to access the same props that
you could add with like a style prop on
a regular element. But it allows you to do
special things as well like media queries and things like that that you can't
do in the style prop. I prefer to use the elements
of the muy components whenever possible when
they're available to us all. You see we have our
head of country search. All right, so looking
at the design here, you'll notice that
we have a bit of margin or padding on each side, and then it's equal on
both of these components, and then we have the
larger piece here. All right, I want to approach
this in several steps. First thing I want to
do, as I mentioned, is we want to style the
actual project itself. So let's work on the
styling and then go from there to be basically want to style these in
a way that both of them can have some padding
on the left and the right. Let's jump into
the header first. The head also changes to a box. The header has two
major elements. It has the war in the world and then also has the
dark mode button. So we're going to start by
using a typography element, let's say, that
we're going to use, we're going to say in the
text we're in the world, this will be of
the variant H one, because every page
needs to have an H one. And then it's probably not
going to be the right format, but we can deal with
that with x, right? Yeah, it's a little bit too big. So let's go SX and
then we will set it to be maybe font size one Ram, maybe two Ram 1.5 Then let's do font
wait like 700. All right, cool.
That's element one. And then the second
one is this button. And the button says
dark mode as a. Yeah, there's also a button
button. Sorry. There's also an icon icon
that's like a half moon, crescent moon sort of thing. Let's search for moons. And this one looks pretty close, so we're going to actually
use this in our button, so I'm going to use. Cool. And we have our little moon
right there. All right. Awesome. The next thing
we're going to want to do here is we are going to want
to put this in one row. So I'm going to use the
SS props and I'm going to just change the display
to flex and save that. I'm going to justify
content space between, I'm going to align
items to the center. Awesome. Yeah. All right, so for the header now I also know that I
want some paddings. I'm going to do padding
of top and bottom is going to be one M and left and right is going
to be two ram. That should be good for now.
What else do we need to do? We want to make sure that, oh yeah, the color actually, if you notice, is
slightly different. I want to actually
set the overall background color of the
app to be like this, light gray, and then this is actually going
to be our white. I'm going to grab that, I'm just going to use this color picker. I'm just going to grab this
color right here and awesome, that's going to be the color of the actual background
of the whole app. What I want to do here, think we're going to go with index. We're going to actually set
the background color here of this overall to be that color. So we're going to go
background color, set it to be awesome. And you can see it just
slightly changed here. It's a little bit difficult
to see just because it is only like kind
of small section, But it will be a little bit more apparent as we start working on the apple
a little bit more. The other thing I
want to do here is set the size of this element, because it's a one
page sort of thing. I want the minimum height of the element to
be 100 ew heights. That's going to be 100% of the height of the view
that we're taking up. And then I want just the
regular height or the, the max height probably
to be fit content. And this will be more
relevant once we start getting a whole bunch
of different results. All right, I'll remove
these extra styles here. All right, cool. So the next thing we're
going to want to do now is actually change the background color
of the header. So the header, now we're
going to go back here and set the background color
to be just white, cool and you can
kind of barely see, but there's a slight
difference here. I'll do one more thing to
sort of distinguish it. You see how there's this
little box shadow here. We're just gonna
add a box shadow to the bottom of this,
this piece right here. So I'm going to copy this
and then add it to our head. And we'll modify
it a little bit. All right, so we're just
going to have it offset, maybe two pixels
in each direction. We're going to make
it a light gray. Save that. As you can see, we have just a really basic sort of differentiation between the two. That's good enough for now. You know, I think we can also do things like change in the color of the button
and things like that. Not necessarily like the
most important thing to do. I think the next sort of
most important thing to do would be to get the selling
down for the rest of this. All right, so the next thing
we're going to do here is work on our country
search container. So our country search, sorry. So in the country search, it's going to be
a whole bunch of different elements, well three. So we're going to
change to a box. First we're going
to have an input, we're going to have the select. And then we're going
to display all of the cards, I believe material. I has a text text input
text field component. And I think we're going to want to use like the
outline one for this. So I'm just going to
grab this line of code here and copy it back in our project and add that
as our first element. So we're going to
have a text field that we import from material I. And then they also have a
Select Select component. And we're just
going to grab this whole thing right
here and use that. Perfect. And we just need to add all these missing imports
so we don't get any errors. I'm just using this as
a template right now. We're going to go ahead
and change it up to suit our purposes. All right, cool. So we have our text input and we have our H or our
dropdown select. I'm going to do one
more thing, and I'm going to wrap these in a box because we're going to actually have our cards
displayed on this page as well. So we'll save that.
And then I'm going to change the display
of this to be Flex. Save that. Awesome.
Cool. So now they're in one line but the
spacing isn't right. Really correct. Right now, the form control is saying full width. We don't
actually want that. We want it to be with
maybe like five rime, ten Ram, because it's
going to be words, but we don't really need
it to be that wide. And then we're going to
actually want these to have space between them as well. So we're going
to do the same thing. Ready to go? Justify content. We're going to set it to
space between six time. Cool. Awesome. As you'll notice, we're still missing that
padding on the outside there. So we're just going
to add another S x pro to the outer box and
add some padding there. So we're just going to go
padding and we're just going to go two Ram all around and say that, awesome, cool. It's a little bit more in line. Now, final thing I want
to do with the text input is make it a little
bit longer because you can see it's actually
quite a bit longer. And I'm just going to make it, we're going to set the
width to be, what, 20 Ram? Let's actually said
it's a 20 view width that weight changes with the actual size of the
screen view width as opposed to M. That'll always be like 30% of the
width of the view. It's a little bit
more responsive. I will do the same thing
with the select here. Might need to change
that to 2015. Or 20. Maybe 15. Yeah, it looks about
right. All right, cool. And then this one can actually
be a little bit longer, maybe 40. Cool. That should be good. Then
another thing I noticed, I just noticed is the
background color is actually white in the swim as well,
I set that to white. Say that. Alright,
awesome, cool. So we have a really
basic text input, We have our select. And then we're going to
do our dropdown card just to customize this
a little bit more. While here we'll notice that the initial text is search for country dot dot. So
we want to change that. Instead of that being the lay, we're going to say search for a country and say that
then here it says age. We really want that to
be filtered by region. We're going to change
that to filter by region. We're
going to say that. Let's make it a little bit more, let's make this 20 perfect. Um, and I'm guessing the background of that
should be white as well. Say that. Awesome. The next
we want to do now is change the actual different options
here, The menu items. What I'm going to do, I'm going to actually
just close this out and I'm going
to start with one. It's Africa, America. Let's go ahead and
type them out. So let's do Africa.
Africa, Africa. And then I'm just
going to copy and paste this few times America. I'm actually going
to do one above it and that's going
to be our all. I'm going to add another one. You'll see why I'm
adding this later, but I'm just going to
make one. That's all. All right, America. One interesting thing
about this API, it actually is not America. It's looking for, it's Americas, like North America, South
America, the Americas. You want to want to
change the value of this menu item to Americas, even though the
display says America. Actually, we can
change to Americas just to be semantically correct. All right, going down the list, we're going to change
this one to Asia and change that to you. And what I'm doing here,
just in case you haven't, you're not familiar with
this sort of keyboard trick, I'm pressing command
D in order to select the word that
I'm working on. And then the next
version of that word, the next duplicate of that word. So I just want to hit
command D until I select all the number of versions of that word
that are in front of me. So we're going to do Europe, and then we're
going to do Oceana. All right. Awesome. So we have our filter by region. Cool. Next thing that we're
going to want to do, we are going to want to create
our cards for our country. So these are going to
be cards that have a few properties, a
few different aspects. We're going to
take in the image, we're going to get the name, the population, the
region, and the capitol. Okay, cool. So I'm
going to create another component for
this call it card. Say that right now, I just want to see what it looks like with some mock data. So I'm going to go back to my country search and I'm going to create
something called, or just an array of
strings for mock data. So let's do mo data. Actually let's just do
an array of objects. Let's just do an array of
countries. So let's do Germany. Let's do United. States of America, and we'll do Brazil just
like in the example. All right, cool.
We'll save that then. Now what I want to
do, as you can see, we have our box with
our form control, our input and our
select component. We want to go outside of
that box and then we just want to do our
loop through that. We're going to do here,
we're going to go mock data. Then I want to map over that
mock data for each country. I want to return a card card card material. Save that. Oh yeah. Every time you
use map, you need a key. So I'm just going to set
the key to be the name of the country for now.
We'll save that. All right, cool. So
if I go to our card, we should just, yeah, we have three countries
in our mock data. It's basically the loop for the number of times
that we have the country. So we have three cards.
Awesome. Let's go ahead and spruce up
this card a little bit. Actually has a component
called the different cards, but we want to use one
that has an image. Um, maybe the media card. I think this might be
the best one for us. So I'm going to go ahead and copy this information
right here. And we're just going
to create the card, save that and just add all
of these missing imports. Oh yeah, I did name it card. All right, so let's import because I name the actual
component itself, card. There's a conflict because we're importing card for material Y. I've created
something called cards. So I'm going to name
their card card just so it's different and
there's not that conflict. All right, I'm going to remove
a couple of these pieces. Like card actions,
we don't need that. We're literally just looking
to display information. And then, yeah, that
should be pretty decent. The height of the image
and the max width. I want the max width to
be maybe 20 view width, maybe we'll just set that to be the definitive
width because we're supposed to be able to
fit four cross 20 width. And then I'm going to
actually go back here and should wrap it in a box. Yeah, let me wrap it in a box. And then I'm going to turn
this into a flex box. I'm going to say
that, awesome, cool. So now they're starting
to spread out. Let's add one more country. Let's do Jamaica. Just so I have the four across, I can kind of get a feel
for what that looks like. And then I want to
justify content. I want to space evenly, I believe. No space around. Space. Space between. I want space between again. All right, Cool and awesome. So yeah, we have our
four cards right there. They all say lizard
right now because that's what the mock data says.
But we'll work on that. All right, I just want to touch up this little
piece right here. There's not enough space between the card and the actual input, so I'm going to add some
margin to this upper box, so I'm going to
go margin bottom. Perfect. And then I'm just going to touch up
the card a little bit. So I'm going to set the height
of the actual card to be, let's say ten view
heights that too small. Maybe 15, maybe ten is alright. And then we're going to end up passing in some
properties from, from the API itself
once we get them. So I think we're pretty decent
on the overall styling. There's one more thing
I want to do though, just to allow us to do
and work with dark mode.
7. Dark Mode & Zustand: The last thing we're going
to want to do for styling is to work on our dark
mode Materially, I actually has this really
awesome feature where it provides you with a default
theme that's in light mode. So what I'm going
to do is actually try and target that
light mode theme and just have it flip
between light mode and dark mode depending on which
mode we want to be in. So we're going to light,
we're going to leverage that for our app
here to access this. It lives in a couple
of different places. If we look at our app score app, you'll see that
there's something right here that's
providing the theme, a theme provider,
and it's providing something called
the light theme. So the light theme, the
light theme has been created using the create
theme function here. And we're going to
just check that lives in the styles
in the theme folder, in a file called
light theme options. So if we just check
it out right here, we can see that as
a pretty basic file and it should be pretty easily to create a dark mode
version of this. So what I'm going to
do is just copy all of this and create a
new file and call it dark theme options
and paste that. But instead of wherever
it says light, I'm just going to
change it to dark. And I'm pretty sure
this is going to work. Just going to let
us flip between dark and light. Awesome. So we have that going. The next thing I'm going
to want to do now is I need to basically insert
this at the right point. So if I go to app, basically what I want
to do here and it's not just going to be here in this portion of the app,
it's going to be all over. So what I'm thinking is that I want to install Zustand in order to manage this simple
piece of global state. We could sort of prop
Joe the whole way, but I think this is going
to be a little bit cleaner. So if you're not
familiar with Zustan, Zustand is like a
Redux alternative but a lot more simple. It has a lot less sort of
boilerplate to get started. So we look up Zustand, it's basically just a
way to manage state. Yeah, this is the doc, I'm just going to really
quickly install it. Then I'm going to
create a store. I'm going to create a
new folder called store. I'm going to create a file
in there called index TS. What I want to do
is literally just create a store from Zand. I'm going to copy
their formatting here. Um, Oh, and it's
complaining about the type. We'll fix that. Yeah, I want to basically create
this hook called store, which is going to create a store that we can just have
our global state living. So I just really
need two props is dark mode and it's going
to be false to start with. And then I want to
toggle dark mode. What that's going to do
is let's remove this. It's the mode is dark mode, it's going to take that
piece of state and then it's just going to set it to
the opposite of what it is. It's going to, let's
say back there, it's going to be the
opposite state is dark mode. When I hit Toggle dark mode, whatever dark mode is, it's going to be the
opposite of that. One last thing we're
going to do here is add the types we're
going to create. This is the store is dark mode, it's going to be a bullion. Then we're going to
toggle dark mode. This is just going to be a simple function
that returns void. Then we're going to set
store, store, state. We're just going
to call it store. Say that and cool, now we
have fixed our type error. Now we can access this store from anywhere
in our project. So if I go back to apps
X and I can now hook into this and basically access the value
of is Stark Boat. So how we're going to
do this is we want to copy this functionality here. We're going to go into
our component here, make it a little bit bigger. And I'm going to go
constant is dark mode, you're going to go store. We're going to import
that. Oh, you know what, I forgot to export it. Make sure you export the store because otherwise you'll
import the wrong store. So we're going to export store
and import it from store. And they're going
to state dark mode. This is all you have to
do to set up the state. It's super straightforward,
super simple. If you haven't seen my other
video on how to state, we do the exact same thing. This is in the to do at project. It's really, really
straightforward, really simple to use. But it then I'd highly
recommend using it because, I mean, look how quickly
we just set up the state. So based on whether or
not it is dark mode, I want to show the light
theme or the dark theme. So I'm going to do
a quick check here. So if it is dark mode, I
want to use the dark theme. And let me just import it
and create the dark theme. And import it, we're
going to go dark theme. And if it's not then
we're going to want to do light theme and
say that, awesome. All right, so the
next thing we're going to do is we need
to actually turn it on. Because right now it's
not doing anything. Right? Nothing's
triggering that togle. So if I go back to the header, I want to go to the button here. And we want to do
the same thing. We want to, we want
to access the toggle, which was this
format right here. And we're going to
do Toggle Dark Mode. And it's going to
do the same thing. We're going to import
the store from the store and state
toggle Dark mode. We're going to save that. Awesome. It's recognizing
that's a function. And then on click here, we literally just want to
call toggle Dark mode. If we hook this up correctly, when I hit the dark mode button, it some stuff should just
turn dark and some stuff should remain If we
click it, awesome. So it's not perfect because
we've done a lot of customizations ourselves like
with the backgrounds here. But this is a really
good first step, so we know that it's working. Now all we need to do is
hook up the other pieces. So you'll see that this
background doesn't change. That background doesn't change, that background doesn't change, and this background
doesn't change. So we've got a couple of
backgrounds to sort out. So if you go back to, or
actually we can start here, so if we grab is dark mode from the same store that is
dark mode and save that. Then if I just do another
check in this line right here. So if I go is dark mode and
if it is, I want it to be. Let's go back to our design. I want it to be this color.
So let me grab it real quick. This is for the header. Actually, this color
is the one I want. I'm going to grab that.
If it is dark mode, I want the background
color to be that. If it's not, I want
it to be this. And save that if we toggle it. Awesome. Working really well. Cool. Next thing I want to do is change that
for the country. Search the whole app. So that's going to be
here in our index. We're going to do
the same thing here. We can actually literally
just copy dark mode here. Paste that in there. And then import the store, save that. Then we're going to change
it to this color here. Grab that there, that. And then we're going to go is dark mode and ask the question. And we're going to do
it. Is going to be, if it's not, it's going
to be that we're going to save that then. Awesome. So if we've done that right,
awesome. That changes. All right, Final
thing we need to change are these Toggle, I think those are the same
as this color up here. That's going to be in
our country search. So we can do the same
check in Country Search. Save that. Import that. Oh yeah. Wherever it's FFF Nags, change those two
to be this color. Here to go is dark mode and same thing here, dark mode. And there's definitely a more
succinct way to do this. This is just sort of get
it done quick, save that. Alright, Awesome. So if I flip the dark mode
now it works sweet. All right, so we've gotten the dark mode sort of taken care of and sorted so we can kind of move past our styles
like little stuff, little tweaks to do, a little touch ups
to do along the way, especially once we import our images and things like that. But this is like a really
good start for now.
8. Using an API: All right, so if we take a look at our API
information here, our endpoint, Ok. We can basically grab all of the countries from
this one link. Now we're probably going
to end up filtering it, but this is a good
place to start. We're going to
want to grab this. Now, we have to think about
the hierarchy here, right? We have our input, we have our filter,
and we have our car. It's all in the same
component right now. And that's done intentionally to make this a little bit
easier for ourselves. What we're going to do
here is actually within the same component is where
we're going to do our fetch. Now in a cleaner sort of set up, we can start to
separate these pieces, but as the MVP, we can
just start by putting it all together and getting sort
of a basic working version. How we're going to
do that is we are actually going to
call in a use effect. We are going to do a fetch from this API and
that should be in quotes co. What fetch allows us to do? If we look up the
documentation here, fetch allows us to essentially
receive a response. Basically, we're
sending a request. It's a method that we
use to grab a resource from whatever that endpoint is, and then we can transform that data into something usable. What we're going to do here
is we're going to fetch it, and then we're going to
chain a dot then to it. So we're going to say fetch. Then we're going to grab the response because we
want to make sure we don't always know whether
or not our response is in Json format or
if it's readable. We're going to
change it into Json. We're going to go
response to take that response and we're
going to turn it into Jon. All right, So now we
have a Jason response. Awesome. Final thing we're
going to want to do, and we should actually create
something to save this in. We're going to
create a data object or a data variable and we're
going to set the data. When this is done, we're
going to use state. Data is just going to
be an empty object. Now we need to import
state, so it works. Yeah, we did that. Do, then they're going
to do one more, donning, take data and then
we are going to set data to be data.
We're going to save it. We should be good
to go. One thing I want to do now is see
if this actually works. I want to console
and see if we're getting our results.
The console here. Awesome. You'll see that
we have 250 results here, which is the number
of countries. And I just want to, so we
don't create infilooplet me refresh the page that
is creating an infill. All right, and we're
just going to pass an empty array here to stop the infinite loop. So
if we just refresh. Awesome. So we've gotten
our data perfect. So if we look at an individual
piece of data here, if we look at an
individual country, I'll describe the first one of, so we'll see that we have
a lot of information here. All right, so this
is Turks and Kakos. You'll see that there's like
a ton, ton of information. Now we don't want to
over fetch the data because it's going to be very expensive queries
back and forth. So what we can do, as the API says here, we can actually just fetch
the fields that we need. So we can do all
question mark fields and then equals whichever
field that we need, right? So we know that we need
probably the flag, we need the population, we
need the region, the capitol. And we need the name following the format of this
data structure here. We can actually
change our query, our fetch on line 25 here. And so we'll do the all, and
then we'll go fields equals, so we'll just make sure
we're doing the right thing. Yeah, fields equals,
and then we'll just separate them with commas. All right, cool. So we'll
do fields equals name. We need flags, we need capital, we need population, and we need region. And
we'll save that. And I think that's
everything we need. So if we refresh, we should still get 250 results. Get all the
countries, but if you see the data is
already much less so. We get the capital,
we get the flags and PNG and SVG form. We get the name, we get the population,
and we get the region. Awesome. So we're
already getting a lot less data and
that's going to make our queries
that much easier. Perfect. So the next thing
we're going to want to do now, actually, if we
take one more look. You'll notice actually that the data is in a very
interesting shape. The capital is actually
within an array. So we want to basically pass this data to our cards, right? We want to just have this go straight through
within our cards. We're going to want
to take in all of this information. Yeah,
let's do it like this. We're going to pass, then we're going to pass flag. And that's going to be
flag, Oops, country. Flagg. And then we're
going to pass population, and that's just going to
be country population. And then we're going
to pass in region. And that's going to
be country region, then it's going to be
country name.com All right, so what am I doing here? Right, I'm creating
all these errors. So this data, which is actually, we're going to use our
real data in a second, is going to map
through each country. So for each country we
want to go and grab, and I'll change it actually, the name we're going to
want to grab the country. And then we want to go into the name that is provided to us. And we want to grab
the common name because the common name is the name that we're
going to go with. You could also go with
the official name, but sometimes the
official name isn't the name that your
user might search for. So I found that the
common name based on the API is a little
bit better to go with. Then we want to grab
the flag, right? The flag is the actual image, the location of the image that they have uploaded to a CDN. I'm going just going to
go with the PNG for now. We could change the
SVG if we wanted to. Totally up to you,
but we're going to go flagg and that's
going to be our flag. We also want to
grab the population and the population
actually is not nested. It's like right
there as a number. So we can just go country dot
population and grab that. We're going to grab the region. Same thing as just a string. So we're going to
grab that region. And then the key is
just going to be the name of the key is going to be the name
of the country. Country.name.com
because every country should have a unique name. Awesome.com. Awesome. So what
we're going to do now is we are going to
go ahead and we are going to pass
this into our card and basically set it up so that it can take
in all of this data. So we're going to create
an interface here. This is just so we
can define our prop, we have the name which
is going to be a string. We have the region, which is also going
to be a string. We have the population, which is also going
to be a string. We have the flag, which
is going to be a string. Oh, you know what, Actually, we forgot about the capital. We also need the
Capitol Capitol. And this is an interesting one. So it's going to actually be Country Capitol bracket zero. It's going to be the first
string in that array. The first object in that array, which is a string,
will be the Capitol. That's also going
to be a string. Save that region
population flag. I think I got
everything. All right. And then I'm going to
pass this into here, so name region,
population, flag, capital. And I'm going to pass props. I'm going to the type
props and save that. All right, cool. So
we have that working. The next thing I'm
probably going to just want to swap this over to use data because it's
giving me a lot of errors. Data. Oh, and you know what, It's, oh, it's giving me an
error because it's not of the array type. So it actually needs to
be an array of objects. So that to be an
array of objects, it's probably also given me errors because I have set these, I've basically initialized
a type of this. I could just create a
common, like a country type. I don't have to pass
it in between the two. If I create another folder, I create types, I
go file Indexer. Then every country is going to have a name which is a string. Name is going to be, the name is a common property which is going to be the string. And then we're going to
have a flag which is going to have a PNG
property string. And then we're going
to have a population which is going to be a number. And they're going
to have a region which is going to be a string. And we're going to
have a capital, which is going to
be a string array. All right, if I can import, if I export the type of country, let's see if this
works and I import it. To import? No, no, it still wants a
sort of basic type. All right, so oh, maybe
it works actually tree. Okay, cool. So we'll just create the object here and
we'll initialize those. We name is going to be a string. Name is going to be of common, going to have a common property which is going to
be of type string. Basically what this is
looking for is like an initial value before
the API fetches. What we're going to
do is give it to it. It wants to know okay flags PNG hasn't returned anything yet. What do we want it to be
until we get a response? So we're going to type in flags and as we know from our API, we can even just look at
our initial response. Actually, I don't
think I have it up, but we know that Flags has a PNG property and we're just going to initialize it to be an empty string for now. And then we're just
going to go down the line and do the same thing. So we're going to go capital. Capital is going to be an array. And it's going to
be an empty array. Or an array with a string
for now can read capital. Actually, might country. Let me remove this type. Okay, there we go. Doing better. Oh, I 'cause I spelled it wrong. Capital, Say that. And population,
population count. Oh, I just need to add it.
So we'll add population to be zero and we'll do region
to be an empty string. Alright, awesome. So I think
we've gotten rid of all of our type errors. Cool. So we're getting so many results we can't even
display all of them. We need to have the flex wrap or something like that so we don't get
so many results. All right, so we can get rid of our mock data here because
we don't need it any longer. Save that. What other
error can we fix here? Population type number is not
assignable to type stream. Oh, is it a string type? Type is a strip here, so it's
actually span number. Cool. That's a great thing
about type script. I mean it'll find
these little errors and make sure that
you don't make them like throughout your entire
project, but All right, so let me go ahead and
create a wrap on this box. Awesome, there we go. So we
have all of our countries, there should be 250 boxes. What I'm going to do now is actually utilize this data in the actual cards themselves. We're hoping to
our card component just give a little
bit of margin on the bottom just so it
looks a little bit nicer. Where it says lizard, we're
going to change that name. Let's check out, actually
it seems really small. We're going to the, the font size to
be like one ram. And we're going to change
the font weight to be about 700 because it
seems really bolded. We're going to say that
we have our names. Then we need the population, the region, and the
Capitol. All right. Using our body two. We're going to go, I'm
going to use the tag, so it's just the
regular bowl tags I'm going to tell you in population then I'm just going to
copy and paste this. The next one was I
believe was region. Region and the capital just
typing capital that awesome. Then finally we want
to access the image, so we're going to just
type in flag here because that's going
to be our PNG source. Awesome. Basically, with a
couple simple props that we've passed in from our
country from the API. We literally just passed them to our card
component and then we've just access them just like we would passing
props or anywhere else, and displayed them in our app. Our app is 50% done, maybe more. We've done like our
initial sort of test with the API and the logic there. So
it's going pretty well. Now the next thing we're going
to want to do is we are. All right, so we have our app
all formatted and styled, but the next thing we're
going to want to do is actually add
some logic, right? Because right now if we type
in anything that we type in France, absolutely
nothing happens. So we want to add in that logic, and we'll do that in
the next section.
9. Adding Search Logic: All right, so the
next thing we've got to do now is actually put in that logic to make sure that when somebody
types in a country, in the search bar
up here, that it actually returns a response. Right now, we do
absolutely nothing. There's no filtering happening
on any of these results. So let's go ahead and
implement that now. All right, so how we're
going to start with this is that we
want to essentially filter through all the countries
that we have as options, from our data,
from our API call. I'm sure, well, one way we could do this is
like through API requests. But we can actually
really simply filter this on the client side, like based on what data
we already received back, since it's a very, it's a fairly low cost
call relative to, you know, a larger
application which is fetching like tons and tons of
megabytes of data. What I want to do
here is I want to go to the country search and we're going to do this
within this component. What I want to do
here, I want to, I want to create a variable call the filtered countries
and I want to set those. I want to initialize
this to be data. Whatever data is, is what filtered countries
is going to be. This is going to be
what we loop through. If I change data to be
filtered countries, we're going to leave
that for now, all right? All right, so yeah,
filtered countries are going to be what
we loop through, but we need to set it up, so we need to initialize it. When we type in here, we want something to happen, we want some sort
of F to take place. We can access that using the on change prop in
the text field. We want to basically something
like filter countries. Filter countries,
Filter countries. I know I'm going to
want to pass the event because I'm going to need to
target that value in there. Let's create this
filter countries, synovus constant
filter countries. And passing in that event
we are going to say that we want to set
filtered countries to B. We want to filtered countries and we
want to filter them. We want to filter each country for country name, country. And we'll do it to lower case to make sure that we're actually
getting the same value. We're going to
transform both of them. We want to see if the, the common name of the
country in lower case, if it includes anything in target value to lower case,
they're the same case. There won't be any mismatch
there and that should work. We're getting this error
because we need to give it a type cool and
filtered countries. All right, so I'm actually
calling the function, alright. Alright, so now we
have it setting. So it's filtering through filtered countries to see
if that is the value. All right, and then what we
want to do now, we want to, we want to return that,
we want to show this, we want to show filtered
countries instead of data and say that. And I think, yeah, we're
getting an error here. We're basically just
getting the default because we need to
wait for this data. What we want to do actually set filtered countries in here. So we want to set data, then we ought to want to
set filtered countries. So we might just be able
to get rid of data. Right. Okay. And then
it auto does that. All right, perfect. So we
have filtered countries. So now if I type in
France, awesome. So it's searching for France. So let's just review
what we did here. So we created this function
called filter countries. It sets the filtered countries
to be whatever they are, so the initializes data
and then we want to filter through each country and
search for the country, the name of the country,
the common name. We're transforming that
common name to lower case, and we're checking to see if
that string value includes whatever we're typing
in our search bar here. So if I type in, you know what, I think we also
need, we're going to have to fix a
couple of errors. But if I refresh, it works cool. So you'll notice that there's already a couple of
errors you have to fix. But the initial
concept is working, so we're moving in
the right direction. All right, so one
error that we just noticed is that if there's nothing in there,
it doesn't reset it. So let's see if we can do an FL to set it to be
the correct value. So we could say if target
value equals equals this, if it equals is just
an empty string, we want to set filtered
countries to be data hops, data else we want to set filtered countries
to be what we've done. All right, type in
that and then, yes. Okay, cool. So if I back
space now it works. Awesome. That's one
error that we fixed. The next thing we're
going to want to do, so we can filter by country, but right now we cannot
filter by region. So we want to add the ability to filter by region as well. So we can actually
start to utilize this sort of built
in handle change that was included with
our form element. We can just change the value
to be region and we'll, we'll change this to be region, so we'll just sort of leverage
the initial set region. All right, cool. Yeah, we can basically utilize this handle change event
to set our region. Now when we choose
a different region, it should just
automatically set it. The issue here is now we're
going to need to filter by both region and
filter by country. So we need to think about how
we're going to do this in a logical way. All right? I think what I want to do here is like a combination of things. I want to create
another handler. So I'm going to
create handle typing and it's going to take an event. I'm going to create another variable, constant search value. This is going to be whatever
they type in this input. I'm going to create a
variable to hold that. I'm going to go state,
going to start with a stempty string handle
typing it is going to be set search value
to target value. And then I'm going to call this, they type when anybody
types in the app. So it's going to do
that. Awesome. And we're just going to get it further. Paratypes. Awesome. Cool. Now we have that search value stored so you can access in
more than one place, this filter countries might end up going away transforming. The next thing I want to do is within like a use
effector use memo. I want to check for
both the region, I want to check for the region and maybe check for
the filter as well. So let me start with a use memo. And what I'm going to
do is I'm going to create an empty array
called countries. And I'm going to then do a check if region does
not equal string, right? So we know region is starting off as an empty string valve. If it's not a string, we
want to do something, right? If region does not equal string, we want to set
countries to be data. Or is it filter data? Data. Filter for country then. If that country, region equal equals
region, cool. Yeah, we want to check, we want to basically set this array of countries to be
whatever data we have. Yeah, countries is going to be. Taking the data, all the
data we get from the APA, we're going to filter
it by country. If that country has a region that matches whatever
region we set it to, it's going to go into
that country's variable. Cool. Then we want to
set the filtered data, but we also want to consider what we set the filtered data, like how the text, the typing bit comes into this. Let me think about
this for a second. All right, so we
basically want to pass like a similar logic. So if region does that, then we want to check
for the search value. Search value does not
equal empty string, then we want to do this check, we want to set the filtered countries to
be basically this, right? We want to do this, but down here, so we're going to take
countries, save that. Then instead of
target dot value, it's going to be search value.
I'm going to save that. Not sure to work because
we basically just taken what target dot
value is and save it as search value. Okay, cool. So we have two, if
we probably need some else's search value is set, region is not null, right? We want the countries
to filter for that. If the search value is not null, we want to then filter
for the countries. But if the search value is null, then we just want to set filtered countries
to be countries, right, no extra filtering. The region does equal. Nothing like if
there's no region, then we want to do a
similar check here, right? We want to basically
do this again but then set this to data. I think, yeah, set it to data, but instead we want to do the set filtered
countries and we're going to do it on data, I believe is the data
filtered country. We'll do it on filed. If the search value is not null, we're going to take
the filtered countries and then filter them else we're going to just set the filtered
countries to be data, the region, if there's
no region set, but if the search
value is not nothing, we still want to filter
by the search country. That's something
we might just lose that filter country's function because it's not
really as helpful. But if the region is, the search value is
also an empty string, we want to set the filter
countries to data. This should work. We just
need to add our dependency. So it should be data region and data region
and search value. Save that. I think
that should work. I think that should
work. Let's try. Let's go France. But let's go and then let's try and filter
by reach scope. Europe, okay? America's okay. Africa. Yes. All right. So it works awesome. Cool. Cool, cool, awesome. All right. Cool. So
that works great. So the next thing, yeah. So the next thing that
we're going to want to do, I think what I'm
going to want to do now is I want to set it. I wanted all to work. I basically I want
you to be able to reset the region because right now without the all you
can only just set it. You can't unset it, right? You can't reset it
if it's set to all, for it to also return
all of the region. If I do region equals
region equals equals, all works, no, it doesn't work. What I'll do out here
actually is just change the value of all to be an empty string so that
when I go to Africa, America, Asia, and
then I go back to all, it just returns out
of an empty string. Really simple, clean, fix, cool. Let's see what else is there. Is there anything
else I can do here? I think the only
thing left to do here is to probably just clean
it up a little bit. It says it wants filtered
countries as a dependency, but I don't know if it's
going to work if I do that. Let me say that and then try. Oh wait, Sorry. I'm not. Yeah, no, it breaks
if I do that. Yeah, So I don't
want to do that. I'm just going to
leave that out. I'm just going to disable the exhaustive dependencies
for this line. Cool. I think, do we actually
use filter countries? Like if I comment this out
and I remove it from here, will the apps run? Oh, that is a bug. It doesn't. All right, so I don't think we actually, I don't think we actually
need filter country. So I'm going to get rid of it and I'm going to get rid
of the column to it here. It's just going to be
replaced by handle typing, which essentially takes that target value
and just gives it a variable that
fixes that problem. Uh, what else? What
else can we do here? Oh, we can take out
this console law. We don't need that anymore. So by data, yeah, that
might be the fix. Okay, that was the fix. So I was getting this
error where if I typed in a couple of letters
and I went to a region, if I went back to all,
it wasn't sorting it. So that's because I
mistakenly, I made a mistake. I should have said data on line 60 or I should have said
filtered countries, which was what
we're filtering by on line 60 to actually be data. So just going to use data, we're not going to use
filtered countries. We are going to use filtered countries just not
at that point. Awesome. I think we have
everything we need here. I think we're pretty
much set up to go cool. I guess other things
that you could do with this project is make
it mobiley responsive. So to make it, you
know, turn into a sort of like dropdown view that
they have here as an option. You know, any filter
by region and it's just one country after the other and make a mobile version. That would be another
cool project to do. You could touch up the
dark mode, you know, get a better icon that's a little bit more in
line with the design. A bunch of stuff you could still do if you wanted to
on this project. Totally up to you if you want to sort of
keep going with that. And then you can also add a sort of individual page here for the individual
countries that really just displays their
information there. So a lot to still be done
with this project, but yeah, hopefully that was
helpful for you and you really were able to learn how to use an API with the country
search and you're able to work with APIs
in the future and incorporate them into
your future projects.
10. Conclusion: We talked about a lot in this
video from the origins of react to building out your own fully functioning
country search web app. Going forward, you
should be able to tackle any API project
that comes your way. Just remember to look up
something when you're unsure and to comb through stack
overflow as necessary. I'd love to see how you decided to implement your web app. So please leave a link to your code or the hosted
site in the Projects and Resources tab so that I can see all of the hard
work that you've done. I do read every comment, every review, and look at
every project submission. So if you do have any questions, please feel free to
leave a comment in the review section below or
to reach out to me directly. Check out my profile page for more information about that. If you'd like to learn
more about coding, check out the other videos
I have on my profile page. I also have videos on HTML and CSS available on my
Youtube channel website. I'll link those below and on my profile if you're interested in learning those languages as well. And I'll see
in the next one.