-: In the last section, we started talking
about what the Redux Promise Middleware does for us.
We're gonna get started working
on our own middleware in just a moment,
but before we do, there's one last quick thing
I wanna tell you about.
Inside of a redux application,
there's effectively not an upper limit
to the number of middlewares we can have.
Our application at present only has one middleware,
the Redux Promise Middleware, but we could very easily add
in other pieces of middleware as well.
When we add in other pieces of middleware,
we refer to them all being put together
in a series as the "middleware stack."
When we have multiple middleware and we dispatch an action,
or we return an action from an action creator,
every single middleware inside
of our application has the ability to inspect that action
and take some operation on it.
Like, say, logging it or modifying it, stopping it,
whatever it might be.
So if we return an action from an action creator
we can imagine that it gets sent
to maybe the first middleware
inside of a chain of middleware.
This first middleware right here has the option to look
at that action and decide whether
or not it wants to do something with it.
So maybe for Middleware #1 right here,
maybe it looks at that action, it looks at its type
and payload property, and it decides, "You know what?
I don't care about this thing at all.
I want this to just go
onto the next middleware on the chain."
So this middleware will take the action and forward it
on to the next middleware.
In this case, Middleware #2.
Now, maybe this middleware inspects the action.
It looks at its type, maybe it looks
at its payload as well, and it says, "You know what?
This looks like it's something important.
This looks like an important action."
And so maybe this middleware decides
that it wants to console log the entire action,
just for development purposes.
So you and I can look at our log and say, "Oh, okay,
it looks like that action just got dispatched
and it just went through all my middleware."
After Middleware #2 does that console log,
it can then forward that action
on to the third middleware in the chain.
And then again, maybe this one says, "You know what?
I don't care about this thing."
After an action has flowed through every single middleware
inside of our chain, it then automatically gets forwarded
on to all the reducers inside of our application.
Okay, so the idea here is
that we can have multiple middlewares.
Each middleware has the ability to inspect an action,
and if it doesn't care about the action,
then it has the ability to forward it,
or pass it on, to the next middleware on the chain.
So now that we understand the idea of chaining together
middlewares, let's start talking about the middleware
you and I are gonna make.
So you and I are going to build from scratch
the Redux Promise Middleware.
So essentially, the same middleware that we've been
making use of throughout this course
to go and fetch that list of comments from
that outside API,
you and I are gonna build it up from scratch.
We're gonna work on one other middleware as well.
So this is gonna be kind of an introduction one,
and then we'll take on a slightly more different,
little bit more complicated one later on.
All right, so let's talk
about what this thing needs to do.
So as you and I very well know,
when we call that fetch comments action creator,
we return an action that has a promise,
or a network request, on the payload property.
That's what's happening inside
of our action creator right now.
So here's that request, or we're calling it "Response."
It essentially is a request from Axios,
and we put that onto the payload property.
So our middleware is going to look at the incoming action,
and it's gonna say, "Hey, on your payload property,
do you have a promise?
Or do you have, like, a network request there?"
If it doesn't, so if the action does not have a request tied
to it, then we're gonna say, "Okay, like, whatever.
I don't care about this thing."
We're just gonna let this action pass through
and we're gonna pass it to the next middleware on the chain.
Now, in our application, you and I are only
gonna have one middleware total for right now.
So there is no other middleware.
So essentially, the action will be forwarded on
to all the reducers of our application.
Now, how about the case in which we do have a promise
or a network request in the action?
Well, if it does, then we fall into the other category.
We have a promise, and we wanna make sure
that we do not forward this promise
on to our reducers until the promise has been resolved.
So we want to wait for the promise to resolve,
or essentially get a response from that API.
And only after we get that response are we going to
let this action continue on.
Remember, the entire key here behind the way
that our fetch comments action creator's working right now.
When we returned the action from the action creator,
it seemed like, magically, we were waiting to
get the response back
from that JSON API before it went to the reducer.
So that's a very critical part
of the middleware that you and I are gonna put together.
We need to make sure that if there is a promise there,
if there is a network request, we wait for it to resolve,
and then we let it go on.
Now, when the action actually gets resolved,
and we get the data back from that network request,
we're not gonna just take that data
and send it on to the reducer right away.
Instead, we're going to recreate a brand new action
with the same type and all the data that we just got back
from that network request.
So we're gonna make a new action, and we're gonna send it
through all the different middlewares that we have again.
Now, again, we only have one middleware here,
but we can easily imagine
that maybe we have multiple middleware,
and you might be curious,
"Why are we creating a new action
and sending it through all of our middlewares again,
rather than just sending it on directly to the reducers?"
Well, think about it for a second.
When we put together our middlewares,
we do not want to write middlewares that depend
upon them being organized in a single certain order.
So maybe you and I eventually put together
another middleware inside of our application,
like Middleware #1 up here that says,
"I want to see actions with comments."
So maybe Middleware #1 up here really cares
about seeing actions that contain comments.
Then let's imagine that as Middleware #3,
we place this asynchronous, or this kind
of redux promisee, middleware
that you and I are going to create.
So down here, we'll put "Redux promise middleware."
So when our action comes through,
if it's the action that contains the promise
like the original action, it will go to this middleware.
This middleware is gonna say,
"Oh, you don't have any comments tied to you.
You just have a promise.
I don't care about you yet."
So that action will then go onto the second one.
It'll go onto our third one.
The middleware that you and I are gonna create is gonna wait
for that thing to resolve.
It's gonna get the list of comments from the API,
and then we still need to make sure
that the list of comments ends
up going through this first middleware as well.
So that's why we're gonna create a new action,
and send it back through all of our middleware,
so that we can make sure that now this middleware
up here gets to see the action with all the comments.
By taking this approach, we don't have to arbitrarily
reorganize the middlewares inside of our application.
Ignore the arrows here for a second.
That's crazy.
We don't have to arbitrarily rearrange them
to make sure that, "Oh, yeah our action goes
through this one and then this one."
So this is a very common approach,
a very common approach to say,
"If we change an action in any way,
rather than forwarding it
onto the next middleware or onto the reducers,
we'll instead make sure it goes back
through all of our middleware again,
so that everything has a chance to look
at this new action that's coming through."
Okay, so after we wait for that request to be resolved,
after we create the new action, and send it back
through all of our middlewares a second time,
we'll look at that new action.
We'll say, "Does this thing contain a promise?"
Well, in this case, after the promise has been resolved
and we've got that data, nope, no longer has a promise,
and so we're gonna fall into the "No" category,
and the action will go onto the reducers.
Now, if this flow right here seems confusing,
don't sweat it, because as soon as we start writing
this code and adding in some console logs,
you're gonna be able to see this flow
in action for yourself.
So you'll be able to play around
with this flow and get a really good idea
of how our middleware is going to look at the action,
decide what to do with it, and then eventually
create a new action and send it back through.
So, now that we have a better idea of what we're gonna make,
let's continue in the next section,
and we'll get started on creating our middleware.