Youtube in React: 43: searching for videos
This is the last feature we will implement as part of this tutorial series.
Youtube MVP, we’re basically just lacking a
It would be nice if we could enter a search term at our top
search bar and get a few results.
Click on the image to see it in high resolution.
2 Searching for videos
2.1. Youtube search endpoint
We’ve already encountered the
search endpoint when we were fetching related videos. However, this time around we will use it to filter
videos by a particular
Please check out the Youtube API explorer to understand how a
Youtube search request must be formed.
We need to make
GET request to the following endpoint
A typical response looks like this:
You probably noticed that we don’t get any information on statistics. So technically we would need to extract the
video ids, and hit the
/videos endpoint again.
This time around we will not do this. So we will just not display the total amounts of views in our
search result. I leave that to you as an exercise. It’s super easy compared to the chaining logic we already wrote in this tutorial.
Again, this is one of the moments when we see the
Youtube endpoint’s limitations.
2.2. Let’s talk about state
We need to store the search results somewhere. Now unless we want to track the history of all
searches, storing the most recent search is totally sufficient. We will just store the most recent search because it’s easier and because otherwise we will never be done with this tutorial series 😁.
It’s also a storage issue. When you do a new search, we basically don’t care about the results of the previous
searches any more.
We will introduce a new top level
object called search in our
Redux state that looks like this.
The query property saves the search query the user has entered. The
totalResults fields stores to total amount of
search results. We also store the
next page token in case we want to fetch more results.
results array contains the actual search results, i.e. the video’s name, the channel name etc.
2.3. Building a Youtube search request
Head over to the
src/store/api/youtube-api.js file and add the following
We make a
GET request to the
/search endpoint. We pass the search query (the keywords the user entered) as well as the
next page token (if available).
Per default, we just fetch twelve new search results. This should be enough elements so that we don’t have any whitespace on the screen. Remember that if we don’t pass a
next page token, the parameter is automatically kicked out by our
2.4. Youtube search by keyword action
results of our
search will go in a completely different part of our
Redux state, we should also put the search-related action creators into a separate file.
- Create a new file called
search.jsand put it inside
SEARCH_FOR_VIDEOS_REQUEST action takes the search query, the next page token and the amount as a parameter. Note that the amount parameter is optional. Per default our
buildSearchRequest function fetches twelve videos (see above).
Note that we are passing along the search query as payload in our
failure actions. Like so, we know the search term to which the fetched
videos belong to.
2.5. Youtube search by keyword sagas
Now that we have our action creator in place, we need a
watcher and a
worker saga to perform the actual network request.
Let’s create a new file for them as well.
- Create a new file called
We listen for the
SEARC_FOR_VIDEOS_REQUEST action. Once such an action is dispatched, we extract the search query, amount and
nextPageToken property from it and
worker saga. We pass all parameters to our
Thanks to our helper
worker saga is dead simple. We bind the parameters to the
buildSearchRequest function we defined earlier.
After that we perform the actual request by using the
fetchEntity function. There’s really not much magic here. You’ve seen this a couple of times by now.
2.6. Wiring up watcher saga with the root saga
We need to plug our new
watcher saga into the
root saga. Otherwise it doesn’t do anything. Head over to your
All we did was add a new element to the array we pass to the
all effect. Now our new
watcher saga is wired up and listens for the actions that that are dispatched.
2.7. Search for videos reducer
We need to update our state when we receive the result of the request from our
worker saga. As mentioned above, we will introduce a new top level element in our state called
search. In here we will store all the information on the most recently performed
- Add a new file called
The structure of our
reducer is very simple.
We only react to the
SEARCH_FOR_VIDEOS_SUCCESS action. If we encounter an action type, we don know, we just return the previous state. Now the only thing we need to do is to implement the
There’s something strange going on with the
video id. Let me explain.
We will use the
VideoPreview component to display our list of videos. The
VideoPreview component expects the video as a key for
React. If you
render lists, you should always provide a unique key for each element so that React an efficiently update it.
Now have a look at our search results response again. Here, the
id is actually not a
string, but an
object. That is, because you can also search for playlists etc. To make every
search result have a
top level id property whose value is a
string, we use the
function. We map over all search results, copy all properties but replace the value of the
id property with the actual
Now the thing is we could have stored the search result as we get them and perform this operation later on. However, bear in mind that this is a rather expensive operation.
We might have to map over the
array over and over again just to make this simple change.
Redux-reselect also wouldn’t be helpful here. Therefore, let’s go with this approach for now.
2.8. Wiring up the search reducer with the root reducer
reducer needs to be plugged into the
root reducer. Otherwise it won’t do anything. So head over to your
src/store/reducers/index.js file and update the
2.9. Search selectors
To later use our
search results in our components, we should create a few
selectors to avoid tight coupling. Let’s think about what we need.
Well, we need a
returns us the
search result. In addition, we also need a
returns us the
next page token. We will need this token in our infinite scroll functionality to fetch more
As always, we will co-locate our
selectors with our
reducer. Therefore, please put the following code into your
We just return a specific part of our
state. There’s no real need to use
redux-reselect here because we’re not computing a derived
state here. We’re just returning some data as we have it in our store.
3 Wrap up
That was a lot of work. But we finished the
search action creators, the
reducer and the respective
sagas and even the
We will make use of them in the next tutorials.
You can find entire code on Github.Follow @productioncoder
Please follow me on Twitter @productioncoder to stay up-to-date. I’m happy to receive feedback of any kind.
If you are interested in more high-quality production-ready content, please enter your email below.