Build Youtube in React 23: fetching most popular videos
In the last tutorial, we created some helper functions to make our life easier when it comes to creating actions and to fetching data.
Now, we will finally make use and fetch some data for the
2. Most popular videos request, actions and sagas
2.1. Creating fetch most popular videos action
Let’s put this logic into a file with a self-explanatory name:
- Create a new file called
actions is now pretty straight forward.
createRequestTypes, we store an object with three
MOST_POPULAR, that is
The request function of
three parameters. First we want to dynamically tell the action how many videos we want to fetch. Since the video description can be quite long, we also want to control whether we load it or not. If we don’t need it, it makes sense to not load it because we will have a lower response time.
We also pass the a next page token in case we want to make use of
Youtube's pagination feature.
2.2 Creating most popular videos request
We now have the action that is supposed to kick off the entire process. But we haven’t yet defined the request and specified its payload. Let’s do that now. With the help of the
Youtube's boilerplate code, this will be quite straight forward. Add the following function to your
As you can see we are just performing a standard
GET call against the
/videos endpoint and pass a few parameters. We want to get back the
snippet, the video’s
statistics (so we can show the view count) and the video’s
content details. Please refer to the
JSON response shown above to see what
snippet, statistics and
We also pass a quite cryptic string for the field parameter to prevent over fetching and to get a faster response. We adapt the fields string depending on whether we want to load the description or not.
2.3 Fetching data with sagas
We have the
actions, we have the request, but we don’t have the
sagas that will do the actual work. Let’s quickly set this one up.
- Create a new file called
If you think about it, our overall data fetching workflow is pretty much the same. First we execute the request and wait for the result. If the request succeeded, we dispatch an action with whose action.type field ends with
SUCCESS. If the request fails, we dispatch an action whose action.type filed ends with a
Let’s create a helper function for that which we can use over and over again. Add the following function to your
fetchEntity function takes in three parameters. The first one is the
request function, i.e. a function that returns a promise. Typically this function is somehow constructed by the
Youtube client library. The second parameter is an entity object. By entity, I mean an object that has a
failure function. That’s pretty much anything we import from
src/store/actions. Remember that we are always bundling three different action creators functions together in an object because we always have the
...args makes the function variadic. This means that we can call this function with an arbitrary amount of arguments. Sometimes we want to pass additional information into our
SUCCESS actions. Therefore, we allow an arbitrary amount of additional arguments.
The method itself is quite straight forward. It will execute the request and if it is successful, it dispatches the action returned by
entity.success. If it fails, it dispatches the action returned by
We will use the
fetchEntity method all the time from now on because we want our code base to stay
2.4. Most popular videos sagas
Now that we have our
fetchEntity function in place, we just need to create a
watcher and a
worker saga. Head over to your
src/store/sagas/video.js file and add:
Once such an action is dispatched, we extract its payload. That is, the total amount of videos we should fetch from the endpoint, the
next page token (if any) and a flag that tells us whether to load the description or not. The watcher saga then passes on the actual work to a worker saga called
fetchMostPopularVideos. In here, we use the
buildMostPopularVideos function we defined earlier to construct a request.
You might have wondered why we use the
bind method here. Well, the
redux-saga call effect needs a
function as a parameter. When we use
bind, it will return a new function with already inserted parameters. We could have also used:
Once constructed, we pass the request to
fetchEntity which will execute it, wait for the result and dispatch the appropriate action when the request succeeds or fails.
2.5. Running our saga
We successfully defined our
sagas but we’re not running them. To run our sagas, we merge them together in our big root saga that will later be run in our store.
This is what the default export is for in
We only need to instruct the middleware to run our watcher saga. If our
watchMostPopularVideos saga detects an action with the correct type (
MOST_POPULAR_REQUEST), it will create a worker saga that will load data from the
We use the
all effect to instruct our middleware to run the sagas we specify in the array.
forking all of the sagas, we tell the middleware to run all of them (currently just one, but more will follow) in parallel and not wait for any of them to finish. In fact, our
watchMostPopularVideos saga will never terminate because we will listen for new actions forever.
This is also why we created an infinite loop with
while(true) in our watcher saga.
3 Wrap Up
Good job, we’re done with the sagas.
However, we still need is the video reducer that updates our state once we receive data from the
You can find all the code in our Github repository.
As always thanks for reading.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.