Instructor: We've now got our UserList put together,
which automatically calls the fetchUsers action creator,
which will fetch our very static list of data right now.
That data then gets pushed back into our user-list component
and our user-list shows up on the screen.
So let's take another look
at the FETCH_USERS action creator now.
So this is where we're gonna start talking
about the topic of our middleware
and what we're gonna do with it,
and how it's gonna be applicable
to our particular app, okay?
So we also took a glance at the fake JSON endpoint
that we're gonna be fetching from.
All we have to do is do a get
to jsonplaceholder.typicode.com/users
and that will give us our list of users that we care about.
Once we make that request,
we will return that list of users here
in our payload instead of this very static list of users.
So the first thing we need to do
is figure out how we're gonna make the Ajax request.
Well, to do that, we'll make use
of a npm library, third-party package called axios.
So to install axios, we need to install it
as an npm module.
So over in my command line, in my project directory,
I'm gonna stop webpack
and then I'll run npm install --save axios.
So luckily axios is pretty small
and it should only take a couple seconds to install.
Cool, I'm gonna start webpack back up
with npm run start.
And we're good to go.
So let's make our Ajax request.
This shouldn't be too bad.
At the top, we'll import axios from axios.
And then inside of the action creator,
here's where things are gonna start to get interesting.
Let's make our Ajax request.
We'll say const request equals axios.get.
This is how we make a get request with axios.
And then we just need to pass in the URL
that we wanna do a get request to.
I'm gonna go back over to Chrome.
Here's our endpoint, jsonplaceholder.typicode.com/users.
I'm gonna copy this
and we'll provide it as a string to axios' get method.
There we go.
So axios, whenever it makes a get request,
returns a promise.
So this request right here is really a promise.
So we need to somehow get the data out of here
and in the very next instant, return it
on our payload inside of our action.
Once that action flows into the reducer,
we'll collect the data and boom, we're good to go.
So if we were to summarize what's happening right now
or what we kind of want to have happen,
let's take a look at a diagram.
So this is kind of what we're hoping
is gonna happen right now.
We're gonna call fetchUsers.
That's gonna return an action
and that's gonna flow into the Users Reducer.
Boom, we got our data, everyone's happy.
We're all done for the day, right?
Well, obviously, not quite that easy.
What's happening here with our payload?
We've got a payload of request and request is a promise.
Now, the important thing to keep in mind
is that whenever we return an action
from an action creator,
it is instantly thrown to all the reducers.
Effectively instantly thrown to all the reducers.
But our Ajax request,
the actual request, the actual promise,
axios.get takes some finite amount of time.
It takes, I don't know, maybe 500 milliseconds
for the browser to complete that request.
So we've kind of got this weird race condition
where on the one hand,
we wanna have immediate access to this list of data
or this payload on our action.
But on the other hand,
we've got a request where the data is not gonna get resolved
for some X amount of time.
So there's definitely something wrong here.
Let's just out of pure curiosity,
let's see what happens.
So I'm going to remove the array here.
We're not gonna use the static data anymore.
And instead, we'll return a payload of request.
All right, so let's save this.
I'm going to...
Well, let's not put any debug statements in here.
Let's just refresh the page and see what happens.
So my kind of intent right now
or what I would love to have happen
is I'm gonna return an action here.
The action is gonna flow into the reducer
and the reducer is going to just somehow know
that this is a promise and pick data off of it,
and poof, there it is, everyone's happy.
So let's give it a shot to see what happens.
I'm gonna go back over to the browser.
Refresh the page.
And nothing. All right.
That's okay, let's see what we got for the debug side.
Okay, so we got nothing at all, just plain nothing.
This is pretty interesting.
Let's take a look inside of our reducer.
I'm gonna go over to our users reducer, excuse me.
And let's just put a debugger in here.
Let's get a really good idea of exactly what's going on.
So I've got a debugger inside the case statement.
Let's loop back over, refresh.
Okay, so we're definitely landing inside the case statement.
Here's the debugger, we definitely hit it.
And you can see all of our transcribed ES6 code.
Let's now transcribe down to ES5
and it looks awfully ugly, doesn't it?
Arg.
Not very legible.
Anyways, the point is that we do
at least have the variable action.
Here's action.payload. Oops.
So let's see what action.payload is.
I mean, we're trying to concat action.payload
into our state.
So we'll say action.payload
and huh, as we kind of probably expected,
we have a promise here
and the promise is still pending.
So here I am inside of my reducer.
I'm at the point in time in which I'm saying okay,
I want this data, I want to consume this data.
I need this list of users, basically right now.
But our promise is still pending.
It has not yet been resolved.
So we've got an absolute chicken
before the egg kind of deal here
or perhaps a better analogy
would be we're putting the horse before the carriage.
We're trying to use our data
before the Ajax request has been resolved.
So this is definitely not a good situation here.
We need to think of a way to not enter the reducer
until our request is resolved.
And that, my friends is exactly
where middleware comes into play.
Yay, so I know it took forever to get here
and I know putting the app together first
was probably annoying
but this is exactly what middleware is gonna help us for
in this very particular case.
So again, our whole issue here
is that we are inside of our reducer with our action.
We're at the point of time where we wanna get access
to our data but with vanilla Redux,
like just very vanilla, we're not using any special add-ons
or anything like that with just vanilla Redux.
We don't have any way of dealing with an action
whose payload or some property of the action
is asynchronous in nature.
So with this kind of setup for this lead-in,
let's continue in the next section
and talk exactly about the middleware
that we're going to build.