Build Youtube in React 30: Most popular videos per category reducer
1 Overview
Let’s continue where we left off and create the reducer to handle the MOST_POPULAR_BY_CATEGORY
event
2 Youtube most popular videos reducer
First of all let me tell you that this reducer is probably one of the hardest and most complex things we will write during this tutorial series. But let’s take one step at a time.
2.1 Update videos reducer
We add a new case block to our videos reducer
for the MOST_POPULAR_BY_CATEGORY_SUCCESS
action. We delegate the parsing process to a function called reduceFetchMostPopularVideosByCategory
. A long name, I know, but it’s very descriptive.
Note that we pass three parameters instead of two here. Remember that the Youtube
endpoint sometimes returns varying video category ids even though we requested videos for one particular category. Therefore, we carry the categories array around which contains an array of category ids
. We already discussed the issue.
2.2 Parsing most popular videos by id requests
Oh wow, what the hell is this? Well as I said, it kinda gets a little bit more advanced here. So what do we do. Let’s go through this step by step. Remember that we fetch the most popular videos for multiple categories concurrently. Therefore, our response is actually an array of responses. If we fire n
requests, we get n
responses back.
There is two things we need to do in our reducer. We need to update our videos.byId object because we just received new information about new videos. In addition, we must store to which video category the freshly fetched videos belong to.
At the very beginning we declare the videoMap
and the byCategoryMap
variable. The videoMap
variable will later be merged into our videos.byId
object and associates each video id
with the respective video. The byCategories
is later used to update the videos.byCategory
state and stores the total amount of results, the next page token
and an items array with video ids
.
We iterate over all responses and first check if the Youtube
endpoint returned an error. If we got an error back, we just ignore it and continue with the next response.
In case we actually got some data back, we call a function we have yet to define called groupVideosByIdAndCatgory
. This function
returns an object that contains a small video “dictionary” (byId
) and an object that contains the content that should later go into the videos.byCategory
object
. Right now, let’s just assume we already implemented this.
Once we have the results, we update our videoMap
and byCateogoryMap
variable and later on merge our new data into our global Redux state
I know this is not easy to understand. It’s probably best you step through it with a debugger to see what it does. But the response format we get from Youtube is complex and we need to transform it into a proper normalised Redux state. Don’t give up here. Remember that you started this tutorial to really understand React and Redux.
2.3 Grouping videos by id and category
We have yet to implement the groupVideosByIdAndCategories
function.
Remember that each entry inside our global videos.byCategory
state is an object that contains the total results, the next page token and an array with video ids. As a first step, we can extract the total amount of results and the next page token. Then we only have to take care of the video ids.
Our approach is the exact same as in the reduceFetchMostPopularVideosByCategory
function. We have a byId
object and a byCategory
object. Our byId object serves as a little “dictionary” where we associate a video id
with the actual video object.
We iterate over each video and add an entry in our byId
“dictionary”. Should we already have some elements in the items
array of our byCategory
object, we just append
the current video id. If not, we create an array with the current video id.
Note that we are using a rather iterative
style here so we don’t have to create new objects all the time.
Again, it might make sense to step through this code in the debugger because it is not easy to understand 🤓. The transformation we do is complex after all.
2.4 Most popular videos by category selector
Now that we have the data, we only need to display it inside of our Home feed
.
Since we have a normalised state, it makes sense to create a new selector
that returns
us an object where videos are associated with its category
.
Head over to your src/store/reducers/videos.js
file and add
Our new selector
depends on three objects inside state.videos
. We need to know which video ids
are associated with a particular category. That’s why we depend on state.videos.byCategory
. We also depend on our big “dictionary” which associates a video’s id with the actual object. Therefore, we need state.videos.byId
. Of course, we also need to know the available video categories and so we depend on state.videos.categories
.
First, we pick the video category ids
and iterate over them. We first get the video ids
for one specific category by videosByCategory[categoryId].items
.
Next we get the title associated with a specific category id
. Finally, we associate a category's title
with an array of videos. So the selector
would return
somewhat like this:
For simplicity, I just included one category title
as key in the example above.
3 Wrap Up
All right, we’re getting there. We now have everything we need.
However, we still need to wire our logic with our Home feed
up
Please head over to Github to find all the code.
Follow @productioncoderPlease 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.
Recent Comments