Build Youtube in React 29: Fetching most popular videos per category
Ok, so what’s next?
Right now, we load the top
12 most popular videos and all video categories from the
To complete our
Home feed, we now need to load trending videos for a different categories and display them accordingly.
2 Most popular Youtube videos by category
2.1. Youtube endpoint
Loading the most popular videos for a specific category works exactly like loading most popular videos. The only difference is that we need to pass a
category id as a parameter in our request.
You can also see what request we are about to do when you have a look at it in the API explorer.
There is one super strange thing here. I performed the following request:
I shortened the endpoint’s response a little bit here so that the code section doesn’t get too long.
Note that I explicitly asked for videos that are associated with video category id
However, if you look at line
17 you see that the video apparently belongs to the category
24. This is one strange thing about the
If you explicitly ask for videos from a specific video category, the returned videos might contain a different
category id. This is somewhat strange. We need to work around that. So when we make the request, we must remember the
category id for which we are requesting trending videos. Otherwise we might mess things up.
On a semantic level there’s a simple explanation for this behaviour. A video can simply belong to multiple categories. However it is strange that the endpoint does not return the video category id we put in the request. Please keep that in mind for later.
2.2. Updating the most popular videos request
Since we are already able to fetch the most popular videos, let’s tweak our function a little bit so that we can restrict the returned videos to a specific category.
Head over to the
src/store/api/youtube-api file and update:
We added a new parameter called
videoCategoryId and give it a default value of
null. Remember that our
buildApiRequest function will kick out all parameters where the value is
null. So in case we don’t explicitly specify a
video category id, we will just fetch the most popular videos.
2.3. Let’s talk about state
Before we move on and create the
sagas and the
reducer, we need to think about how we want to organise our state. We must somehow store which videos are associated with a certain category. In fact we can just recycle the approach we took when we included the most popular videos into our state.
We added a new property called
videos where we associate a
category with a new object. This object contains an
items array with the
videos ids that belong to a certain category id. Since we get the information back from the endpoint anyway, we save the
total amount of results and save the
next page token. As you can see we chose the exact same approach we took with our most popular videos.
You see, things are getting easier. Once we have a good concept we can use it over, over and over again.
2.4. Creating most popular videos by categories action
As always, we need to create the respective actions first when we reach out to the
Youtube API. Since this is still related to videos, we put our logic inside
You probably noticed that we are carrying along the
categories. This is because of the aforementioned fact that the Youtube endpoint sometimes returns different
category ids. You might have also wondered why we use categories (plural) and not category (singular). Well this is because we will be fetching the most popular videos for multiple categories at the same time to get the
Home feed infinite scroll experience.
Apart from that, our action creators look pretty standard. By using
createRequestTypes, we create the
MOST_POPULAR_BY_CATEGORY_FAILURE constants. The three functions request, success and failure make use of these constants and dispatch the respective action when invoked.
2.5. Before we create the sagas
There’s one more strange thing about the Youtube endpoint. I inspected the results I got back from the categories request and it included the
category id 18 (Short movies).
If I try to fetch the most popular videos for this category in the API explorer, I get an error back:
So even though the
VideoCategories endpoint returns a category with
id 18, we cannot fetch the most popular videos for this category.
We already discussed that we will be fetching the trending videos for several categories concurrently, i.e. with multiple requests. Now that we know that some of the requests might fail, we need to bake this into our code. Let’s add a utility function to take care of that. The following function ignores errors in promises. You will later see why this is useful.
Add the following function to
ignoreErrors function takes a function as an input (
fn). It also takes an arbitrary amount of arguments to that function as an input. This is what we indicate with
...args. It means that if we call
n parameters, the last
n-1 parameters are passed as parameters to the first parameter ,which is the
function fn. I know it’s kinda weird. Now if the promise resolves, we just return the result, if the promise is rejected, we just return the error and pretend nothing has happened. You will see later why we need this.
You probably noticed that the
Youtube endpoint does have some issues and that we have to work around them. I know this is kind of annoying. Typically you would talk to the backend guys or you would change your
API, but we have to work with the
Youtube API provides.
2.6 Creating most popular videos by id sagas
Let’s add a new watcher saga inside
This is our
watcher saga. Nothing special here. We listen for the
MOST_POPULAR_BY_CATEGORY_REQUEST action, extract the
category ids from the payload and let our
worker saga do the rest.
Our worker saga is different this time around. Our
fetchMostPopularVideosByCategory has one parameter called categories which is an array of
category id, we build a request with
api.buildMostPopularVideosRequest. Here, we pass
four parameters. We want to load
12 videos, we don’t want to load the description and don’t have a next page token. The last parameter is the
category id. We wrap our request into the
redux-saga call effect. call is an instruction to the
Redux-saga middleware to execute a particular function.
After we created the requests, we execute them concurrently by using the
all effect. The
all effect is somewhat similar to
Promise.all. So it will execute all requests concurrently and will resolve when all requests are successful. And now you know the reason why we create the
ignoreErrors function before. The
all effect has all or nothing semantics. If only one the requests fail, the entire request fails and we end up in the
Now before we saw that there might be some video categories where no most popular videos are available. So in case a request fails for one particular category, we just ignore it and just don’t display it later on. We need to take care of that in our
2.7. Wiring up watcher saga with our root saga
As always, we need to wire up our new
watcher saga with our
root saga, so we can listen dispatched actions.
Please update the root saga inside
src/store/sagas/index.js like so
3 Wrap Up
We’re making good progress. Let’s stop here and continue in the next tutorial because otherwise it gets too long
You can find all the 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.