Over the last lectures we added a lot of functionality and it's all working except for that we never get
redirected once we placed an order.
Now there are various ways of implementing redirection,
one thing is you could pass a reference to that router history prop onto your order action creator
and when you dispatch burger success or fail, or at least for the success case, you could then use
that if you receive it as an argument in this function to call the push method on it.
I don't like this approach too much though
but you can definitely do that.
Now the approach I'll use is a redux only approach,
I'll add a new action type to the action types file so I'll export a new const and I'll actually name it
PURCHASE_INIT,
here, I'll of course also use PURCHASE_INIT as a string identifier. PURCHASE_INIT will be dispatched whenever
we load the checkout page,
now I'll create my action creator for it,
position doesn't matter,
I'll create a constant which I'll name purchaseInit
and this will receive no arguments and just return an action, so just return a javascript object where
the type will be actionTypes.PURCHASE_INIT.
Now I need to export this purchaseInit function in my index.js
file here,
so it's in the order file, purchaseInit and then, I'll head over to my checkout container and there
I want to add componentDidMount and in componentDidMount,
I want to dispatch this action, in this action or in the reducer,
I then want to add a new property to our state where I set something like purchasing to false which is
set to true once we did finish the purchase so that we then redirect.
So let me add the logic here by also adding map dispatch to prop const mapDispatchToProps here, get
the dispatch function here and then return a map
as always and in this map here, I'll have onInitPurchase for example, hold an anonymous function where
I dispatch and where I now dispatch something I have to import from that actions file.
So import everything as actions from that index file in the store actions folder, like that, and I want to
dispatch an action
here, the action is the purchaseInit action which takes no arguments.
So now I can execute onInitPurchase in my componentDidMount method here, so I'll call this.props
.onInitPurchase like this,
we could actually take the WillMount lifecycle here and with that, I'm now dispatching this.
Now I can go to my order reducer and there I'll add a new case, actionTypes.PURCHASE_INIT, the type
I just added and there I'll return a new state object,
I'll add a new property to my state which is purchasing and I'll initially set it to false and oh excuse
me I'll name it purchased and initially it's false. In purchaseInit,
I'll copy the existing state and then set purchased to false here too
but in success and that's the interesting thing now, in success,
I'll set purchased to true.
So now purchased changes as soon as we did successfully purchase
but it's always reset once we revisit the checkout container. And now i can go to the checkout container
and redirect when ever we did successfully purchase something.
So I can go to the summary, to the render method excuse me, where we already redirect when we got no ingredients
basically, now I'll add another constant
in this case where I will name it purchasedRedirect, this will only be relevant if we got props though,
so I'll put it into this if statement here.
And there I'll set this equal to either a redirect
to home, let's say or and for that I need a ternary expression,
I'll set it to null, to not redirect.
Now I want to redirect if purchased is true,
so for that, I need to map that to a prop in mapStateToProps, I'll add my purchase prop and reach out
to state order and there it's also named purchase, this is a prop we just added in the reducer. And then
here, this purchase prop I'll use here to check if this.props.purchased, that's a boolean and so if this
is true, then I'll redirect because then we're done,
I want to leave the page,
otherwise, we're still in the purchasing process
so I'll set this to null. And now I can render purchasedRedirect in our div here and the other paths below
it won't matter then, it will redirect us.
Let's save all files and see if that works as imagined,
if we open our application here, let's build a burger, let's click on order now continue
and it doesn't like onInitPurchase
so let's quickly have a look what's wrong about that.
onInitPurchase holds a reference to a function here but of course isn't worth that much if we don't add it
to our connect function call,
so mapDispatchToProps should be added there,
now let's try again,
let's build a nice burger,
continue,
yes continue,
let's quickly fill out this form
test street, some arbitrary zip code, an e-mail address and let's click order and we are redirected once we're
done.
And now if we add a new burger and click order now and continue, we again are redirected,
do you know why?
it's related to our place where we call onInitPurchase, componentWillMount in the checkout container
is too late,
whilst it does run before render runs, it doesn't prevent the rendering with the old props we received and in
the old props, purchased is still true.
So we can't dispatch this here in componentWillMount,
I'll get rid of
mapDispatchToProps here entirely,
I don't need to dispatch it here.
Instead we want the init to purchase in the burger builder
when we click on the order now button,
so here, purchaseContinued in the end right before we push to the checkout page,
that's the place where we want to initialize a purchase.
So to do this I'll simply add a new,
actually I can dispatch onInitPurchase,
this will hold an anonymous function and dispatch actions
or here it's called burger builder actions, I should rename this because it's really more than just burger
builder actions
so let's rename all of them to actions in the import and down there,
so actions and then purchaseInit, like that.
With that we're dispatching this initialization action here in the burger builder or at least, we're now
ready to dispatch it,
I have to call onInitPurchase and I want to call it right before I navigate,
so this.props.onInitPurchase I'll execute it here. With that change in place,
let's see if this now works, the application reloaded,
I can build a burger, I'll continue, continue here too
and let's quickly fill out that form
with test street, like that, let's click order,
we're redirected,
let's now go back and click order again
and now we can go there without being redirected one more time.
We got to one flaw,
not sure if you noticed it though, on the burger builder,
our price never resets after redirecting.
So this is something I will do or I'll take care about in the next lecture.