Okay.
Our last task.
Well, maybe two tasks.
There's something I want to check before we move on.
Maybe a bug that's hard to spot with what we've done so far.
But I just want to check something as well.
But we're going to implement well, start to implement the checkout page so that when we do click on
this button, of course we get taken to a checkout component.
So back to VS code.
Let's clean this stuff at the top and we will in our features folder we will create a new feature.
So we'll say new file and I'll say checkout forward slash checkout page dot TSX.
And we'll just create a boilerplate for a functional component inside here.
And we're not going to do much with this right now.
We'll defer this to another section devoted to checkout functionality.
But we use typography and we'll just give it a variant of H3.
And inside here I'm just going to specify or put a label in saying only authorized users Is should be
able to see this as we're going to ensure that our users do log in when they do go to the checkout.
Most of our apps are going to be anonymous, apart from things like the checkout the orders page and
when we get to it, the admin page.
But for the majority of our application, it's going to be for anonymous access.
But when they do try and get through to the checkout page, if they're not logged in, then we're going
to ask them to log in at that point.
So let's go to our basket page so that we can update this or not our basket page.
It needs to be the order summary actually and go to this definition.
And where we've got our button.
Do we have the route inside here.
Did I provide that.
I did not.
Okay.
So we'll add a route inside here for the button.
And we'll use the components equals link which we get from React Router.
And then we can give it the two property.
And we're just going to say forward slash checkout.
And we'll also do the same for the other button inside here to continue shopping.
And we'll just paste in what I have there.
But this is going to go to our catalog instead.
And we also need to update our routes to accommodate the new checkout component as well.
So I'll just copy the basket one down and use checkout here.
And we will go to the checkout
page.
And if we take a look at our progress, that should be all we need to do here.
If I click on checkout then we can see the text.
And of course we're not logged in.
So we should not be able to see that text.
But we're not ready for that functionality yet.
That's just a reminder that we need to implement authentication.
But we'll come on to that.
Not in the next section actually, but in the section afterwards.
So we'll have this around for a little while.
There is a bug I think I'm going to check so we can see our basket.
And if we clear our basket, we get the basket is empty.
If we go back to the catalog, we add something to the cart.
Everything looks fine, but I do want to check what happens if we do not have any kind of basket at
all.
And I've got some errors in the console.
Is that a problem?
I don't know, let's refresh the page and let's clear out the basket again and clear this.
It says it's empty.
If I go to the catalog I'll add something in.
And sure, it looks like we do have a problem to solve.
And what we've got here is a non serializable value was detected in an action in the path payload patches,
value value etc..
Aha okay.
So that's one thing to look at.
If I clear the console and I add something else, is this a consistent error or only when our basket
is empty.
So it is an issue and it is something that we need to take a look at and it's coming from our.
Well, it's coming from this page bundle.
It looks like it's not causing us a problem in our user interface, but for sure we need to take a look
at what this is trying to tell us and what we need to do to resolve it.
And if we click on one of these links inside here that help us out and tell us what the kind of problem
is, and it tells us to take a look at the reducers handling this action type, blah, blah, blah.
But it's talking about non-serialized items in my store.
If we click on this and it says, can I put functions, promises or other non serializable items in
my store?
And it's a recommendation that we only put plain serializable objects, arrays and primitives into your
store.
Technically it's possible to insert non serializable items into the store, but doing so can break the
ability to persist and rehydrate the contents.
So what did we put into our store that's non serializable.
If we go back to the error then it's telling us that it's got a problem with the item.
What is the item This does not look like a non serializable object to me, but it is a class that we've
used here and we can see it's got a constructor.
And a class is something that can have methods.
And we already saw from the documentation here that functions are not serializable in a Redux store.
So even though we don't have any functions in our class, that's what it's got an issue with.
And if we go back to the basket API and we take a look at what we're doing inside our add item, it's
this is the problem here where I've used new item for convenience.
It doesn't like this at all.
So we'll change this to instead of using the class constructor we'll just use it as a type.
Or we don't even need to do that.
We can just use curly brackets and then spread the products, and then add on the quantity as the second
parameter inside here.
And of course TypeScript being TypeScript now tells us that, hey, we've got another type of problem
and property product ID is missing in type, etc. so we'll need to be a bit more specific about the
product ID inside here.
So I'll say product ID and we'll set that to the product.id.
And now we're clean of any errors inside here.
So it doesn't like using a class to add something to an array inside our store.
So now we know.
And if we go back and take a look, let's refresh the page and see if we can repeat the behavior and
add something to the cart.
And this time it's clean.
Just to be sure, I'm just going to clear this out of the cart and go back to the catalog and add something
to the cart.
Sure enough, that warning has gone away.
That wasn't actually the problem that I came back here to look at, though.
There is another thing that I want to check.
If we go to our application and our cookies, let's just clear our cookies and we'll refresh the page
so that we really do genuinely not have a basket at all at this time.
If we click on the shopping cart, that's fine.
The basket is empty.
If I go back to the catalog and then I try and add something to the cart, then we've got an error inside
here.
Our nav bar is not updated.
And if we take a look at the console, then we can see that we cannot read properties of null reading
items in our basket API.
So we've got an issue when it's a brand new customer let's say.
And they're trying to add something to the basket for the first time.
The functionality on the back end would be fine.
We've got our basket ID, and I can refresh the page to get the application into a working state, and
then I'll be able to add and remove items from the cart as before.
But it's when it's a new basket.
That's the issue that we also need to correct here as well.
And for this one, these small bugs can sometimes be the most annoying to deal with.
And let's take a look at what we need to do to resolve this.
And inside our basket API, once again, we'll need to check to see if something is a new basket or
we already have a basket.
So inside the on query started for the add basket item.
Obviously we don't need to worry about whether or not it's a new basket for a remove item, but let's
create a variable and we'll use let because we'll change this further down in the code.
We'll use const when this value isn't going to be updated.
And I'll say let is new basket equals false.
Just inside the on query started.
And then we've got our check for our product ID to see if we're working with a product or a basket item.
So just below this line of code we're going to check to see if not draft.
And if we have a basket ID and we'll need to make that optional.
And if that is the case we do not have a basket ID we're going to set the is new basket equal to true.
And then for this code where we're checking to see if we have an existing item, we'll wrap this in
a conditional as well and say if not is new basket.
We know we're working with an existing basket and we can take this code and put it inside that conditional,
so that will still work fine.
The same functionality we had before, but if it is a new basket, then we're effectively just going
to invalidate the cache for the first time.
They add something to a new basket.
Then we're going to invalidate the cache, which means we're going to go and fetch the basket from the
API for the first time that we use this.
So below the await query fulfilled, we'll add a check inside here and say if is new basket then we're
going to dispatch and we'll say basket api dot util dot invalidate tag or tags.
And in parentheses and square brackets we'll specify basket.
And what we should find now is that resolves the behavior.
We're not going to get an instant response.
When we very first add an item to our basket.
We're going to go out and use the original approach we had with cache invalidation rather than updating
the cache.
So let's see if this has had the desired effect.
I'm just going to repeat the behavior that I did before I removed the basket ID from our cookies.
I'll refresh the page and we go back to an empty basket.
And what we should find if we add to cart now, we don't see the instant update in our navbar.
But what we do not get now is any errors.
Our console is clean, the navbar is updated.
If we go to our shopping cart, we can see the item in the cart and everything should work as it did
before.
Now and at this point forward, we're going to see the instant optimistic updates in our user interface
as well.
So that's what we're looking for.
And now we've completed the functionality in our basket.
That's all of it we need for the client side just now.
So we've got to another milestone.
So we're going to commit our changes into source control.
So I'll click on the version control tab and we'll stage our changes.
And we'll give it a commit message of end of section seven.
And we'll commit the changes and sync them up with GitHub.
And we'll wrap up with a summary.