Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
In this video, we'll use Giphy API's search endpoint to add a Gif search feature to our app.
Search Endpoint
https://api.giphy.com/v1/gifs/search?api_key=<ENTER YOUR API KEY HERE>&q=${query}&limit=24&rating=g
Resources
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
The GIPHY API also provides
a Search Endpoint that let you search for
0:00
GIFs using a word or phrase.
0:05
So, in this video, we'll use this endpoint
to create a search feature for our app.
0:07
Users will be able to search for
GIFs by typing into this text field.
0:13
And the search results will be returned
and displayed in the list of GIFs when
0:19
you hit the enter key, or
click the search icon, next to the field.
0:24
So first, in the App component,
we need to change the URL in the get
0:29
method to the endpoint that
returns a search query.
0:34
I'll copy this URL from the GIPHY docs and
replace the trending endpoint.
0:39
This endpoint offers several parameters
you can use to search query, a term,
0:49
or phrase, limit the number of results
returned, offset the results, and more.
0:54
Now the parameter we need in our
URL is the q or query parameter.
1:01
So in our URL right after the question
mark, we'll add a q parameter.
1:06
The value of the q parameter
needs to be dynamic.
1:13
So q should be equal to the text
a user typed into the search field.
1:17
So, let's create a new state called query
and the function to update it as setQuery.
1:23
We'll set it equal to useState and set the
initial value as an empty string for now.
1:30
Now in the get method, we'll change the
URL from a string to a template literal,
1:39
so that we're able to embed the value of
query into the URL using interpolation.
1:45
So after the equal sign,
add a dollar symbol,
1:52
curly braces, and query.
1:57
So right now, we're only fetching the data
when the component is mounted to the DOM,
2:00
since we provided the useEffect hook an
empty dependency array.
2:06
But we want the data to be fetched
each time the query state changes.
2:11
So to do that,
we'll add query to the dependency array.
2:16
So now we need to create a way for
2:21
the SearchForm component to be
able to update the query state.
2:24
We'll do that by creating a function
called handleQueryChange.
2:28
This function will accept
a searchText value.
2:36
And in the function it will update
the query state with setQuery and
2:39
passing it the searchText value.
2:44
In App's return method,
let's give the SearchForm component
2:49
the prop changeQuery,
passing it handleQueryChange.
2:54
This passes the handleQueryChange
function to the SearchForm component and
2:59
invokes it whenever
the changeQuery prop is called.
3:04
So let's save and have a look at
the SearchForm component in SearchForm.js.
3:08
This component has a searchText state
that's specific to the component.
3:15
It gets updated in this onChange event,
3:21
with the text user's type
into the input field.
3:23
And the handleSubmit function is
called when the form is submitted,
3:29
here in the onSubmit
handler given to the form.
3:33
Currently, handleSubmit just
calls preventDefault and
3:38
resets the input field on submit
with currentTarget.reset.
3:42
So inside this function is where
we'll need to invoke the changeQuery
3:47
function that updates the query state,
3:52
which invokes the data to be
fetched by the useEffect hook.
3:54
We'll call the function
with props.changeQuery
3:59
Remember, changeQuery takes one argument,
the searchQuery.
4:05
But how do we pass the query
value back up to the function?
4:11
Well, we do so
by passing the searchText state to
4:15
the changeQuery function callback,
with searchText.
4:19
Let's save and
test our app in the browser.
4:26
In the search field, I'll type cats,
hit Enter, and it works.
4:29
The query returns 24 cat GIFs.
4:35
Now, it doesn't seem obvious, but our code
is easily subjected to race conditions.
4:39
In data fetching, race condition
is when multiple data is fetched,
4:45
but the data doesn't return in the order
you expect it slash want it to.
4:50
Since data fetching uses promises, we
don't know when the data will be returned.
4:56
If multiple fetches
happen at the same time,
5:02
we don't know the order
the data will return.
5:04
To make the race condition
more noticeable,
5:08
let's make some changes to
how our data is fetched.
5:11
You don't have to follow along,
I'm only making these changes so
5:14
you can visually see
race condition in action.
5:18
Right now our useEffect hook will
fetch the data right when the query
5:22
state changes.
5:26
Let's have useEffect wait a random
period of up to ten seconds per
5:27
request by using the setTimeout method.
5:32
The setTimeout method executes a piece
of code once the timer expires.
5:37
We'll pass a setTimeout,
an arrow function, and
5:43
move the data fetching code inside it.
5:46
The second parameter the setTimeout
method takes is the amount
5:56
of time in milliseconds to wait
before running the block of code.
6:00
So we'll pass Math.ceil,
parentheses Math.Random,
6:05
times 10,000 or 10 seconds.
6:11
So now our useEffect hook will fetch
the data after a random period of up to
6:17
10 seconds.
6:21
We're doing this because GIPHYs API is
really good at giving back our data
6:24
quickly, so we added a random wait
period in between multiple fetches so
6:29
we can see the race condition in action.
6:34
Let's save and head over to the browser.
6:37
All right, to see an example of race
condition, let's fetch multiple GIFs.
6:41
We'll search A, B, then C.
6:46
We expect to end up with
GIFs of the letter C, but
6:50
we actually ended up with
GIFs of the letter A.
6:54
If you did end up with GIFs
of the letter C, no worries.
6:58
Sometimes our fetches come back
in the order we expected, but
7:02
that isn't 100% guaranteed.
7:06
So to ensure our app doesn't
suffer from race conditions,
7:09
let's go back to App.js and
make some changes to our useEffect hook.
7:13
We can keep track of which fetch is
the latest by using useEffects cleanup
7:19
function and adding a Boolean
variable that equals to true before
7:24
the data is fetched, and equal to
false when another fetch is called.
7:28
Let me show you how to implement this.
7:34
So, first, we'll declare a variable
called activeFetch at the top of
7:37
our useEffect hook and
set it equal to true.
7:42
This variable will keep track of
which data fetch is the latest.
7:46
So now, when we fetch the data,
7:53
we only want the GIF state to
update if this is the latest fetch.
7:55
So in the then method
where we call setGifs,
8:01
add an if statement that checks
if activeFetch is true.
8:04
If so,
update the GIF state with the GIF data.
8:10
Now to set activeFetch to false
when another fetch is called,
8:15
we'll use useEffect
hooks cleanup function.
8:20
As you may remember, the setup function
can return a cleanup function that
8:24
will always run before
the next setup function.
8:29
We'll type return and an arrow function.
8:33
Before fetching the next set of GIFs,
we want to set the activeFetch
8:37
variable to false, so
that whenever the previous fetch returns,
8:41
it will not change the GIF state
because of our if statement here.
8:46
I know this can be a little confusing,
so let's run through what we just wrote.
8:52
Whenever the query state changes,
the set up function creates a local
8:57
variable called activeFetch and
sets it to true.
9:02
Then we fetch the data,
when the query changes again,
9:07
the previous local activeFetch
variable is set to false and
9:11
a new local activeFetch variable is
declared, and a new fetch is called.
9:15
The GIF state will only update
when the latest data is fetched,
9:22
meaning activeFetch is set to true.
9:27
All right, let's save this and
see it in action.
9:30
In the browser let's search a,
b, and c, and
9:34
we only see GIFs of the letter c, great.
9:39
Let's go back to our useEffect hook and
remove the setTimeout method.
9:44
We only added this to make the race
condition more noticeable.
9:48
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up