Okay, so now that we can fetch the address, our next task is to be able to update the address.
So let's head back to VS code to now configure this.
And if we go back to our account API we created the method inside here to update the user address.
So we're halfway there already.
And let's go back to our checkout.
Step up as this is where we'll use this functionality.
And at the top here let's add the hook that we generated to update the address.
So we'll use const and we'll use the update or we'll call it update address.
And we'll set it equal to the use update user address mutation.
And we'll also have some local state for the checkbox button as well.
We need to know if it's been checked or it's not checked.
So we'll also use local state and we'll have save address checked as the property name and set save
address checked as the method to update it.
And we'll use the use state hook and we'll set its initial value to be false.
Now, in order to get the address, because we're using stripe functionality to populate the address
inside the component, we'll need access to stripe elements.
Now, the stripe react package that we are using comes with a hook that we can utilize.
So I'm going to say const elements equals.
And we can use use elements that we get from react stripe js.
And then in the handle next when they click to go on to the next step in our wizard, if the checkbox
is checked to save the address, we'll check for that.
And then we can update the address on our APIs.
So we'll add an if statement, and we'll check to see if the active step is equal to zero, which means
they're on the address step.
And the save address checked is true.
And just by specifying save address checked here like that will equate to true the opposite of that
if we wanted to check if it was false.
Of course we would use the Not operator, and we'll also check to make sure that we have the elements
before we try and use that inside here.
And we'll specify const address equals await.
And we will use the get stripe address function that we're about to create because we'll need to go
and get this from stripe.
So slightly awkward to get this, but not too tricky.
We'll add a missing function declaration for this.
And where did that go.
And let's go find our function that should be created okay.
So it's created it underneath our component.
I'm going to move this inside our component code.
That didn't work out quite how I was hoping for.
For some reason I was hoping it would appear just below the method I was working in, but that appears
not to be the case.
I'll use an arrow function just to be consistent inside here and add the arrow function, and I'll also
make it async as well, because we need to use an async function from stripe to be able to use this.
So instead of throw new error, let's say const address elements equals elements.
And we can use the get element method.
And then we can use the address to get hold of the address element.
And if we do not have the address element because this is going to return either the address element
or null or undefined.
So we'll need to check that we have this.
And we'll use if not address element.
And we will return null as we cannot do anything else with this method at this time.
And then we're going to need to get hold of the address from stripe.
So we will use const and we'll destructure what we get back from this in curly brackets.
But let's just use the equals and specify await address element.
And then we can get the value.
So what does this give us.
And this gives us effectively the value that's going to contain our address information.
It'll also tell us if the address element has been completed, and it will also tell us if this is a
new address.
But we need to get the value from this so we can look for inside here the value.
But also we want to separate the name and address as well, because our value is going to have those
two different elements, just like we needed to specify this inside here.
This is going to come as a name and address.
And we really want to combine this so that when we do send it up to our API, it's going to be in the
format that our API is expecting.
So after the value I'll add a colon and then we'll destructure the name and the address from this.
And then we can check to make sure that we have the name and address.
And if we do, we can return both the name and the address but combined into a single object.
So we'll check to make sure we have the name.
And we have the address.
And if we do we will return and we'll open curly brackets, will use the spread operator again, and
will return the address and append onto this object effectively the name as well.
And this is going to give the address in the format that we expect it, or our API is expecting it in,
and will also accommodate the fact that the name and address may be undefined or null, and will return
null from this.
Because again, we can't do anything if we do not have these values, we can't send up an empty address
to our API.
So now that we have the address and I'll need to make this handle next method async as well as I'm getting
an error with the await keyword there.
And then we can check to make sure we have the address.
And if we do, then we can use await and update address and pass in the address.
So let's head down to our check box so that we can make use of this.
In fact I've got an error here.
And what is the problem.
And it says types of property line two are incompatible.
And it says string or null is not assignable to type string or undefined.
And the reason for that is there's a slight difference between the type of property we've used versus
what is coming back from stripe for line two.
I'll have made it optional using the question mark in our type.
But stripe is using null instead, so undefined and null are two different things, even though effectively
we treat them roughly the same way inside here.
So let's go back to our users and we'll give line two an alternative value of null as well, to accommodate
what stripe is using.
And if we go back to our checkout stepper, then the problem with the address has gone away.
So undefined is not equivalent to null.
And we do need to specify that if we want this to function based on the way that stripe is returning
that address.
So then we can just go down to our checkout box and use the function we have here.
So let's scroll down to where we have our checkbox.
And let's just move down the closing tag for this, and we'll give it its checked property and set it
equal to save address checked.
And we'll also give it an Onchange event.
And we'll take the events.
And we can use the set save address checked function and use E dot target dot checked which is something
that we get of course from a check box.
So the idea being is that when somebody does check that particular check box, then we can check for
that in our handle.
Next, as long as we're on step zero, when we click on the handle next we're going to check this and
then update our address.
So let's give that a go.
And I'll head back to the browser.
And let's just refresh the page so that we go out and get the updated address.
And looks like I've got an issue now because my user is not currently displaying the address from the
API that's caught me by surprise.
Let's take a look at the console and see what is happening when we do this.
So I'll just refresh the page.
And okay stripes in the mix now.
So we have a lot going on inside our network tab.
So let's go up and take a look at what is happening and where is the request to go and get the address
inside here.
I don't see that happening in the console.
I've still got those two warnings there.
And I've also got a warning about default values not being a recognized parameter.
I'm going to ignore this for now, and take a look at this and come back to this in the end.
Because default values is a recognized parameter, it's in their documentation.
That is how we need to set the address.
So these kind of warnings from this stripe JavaScript, they can be quite infuriating especially when
you follow their documentation to use it, and then they spout warnings in our Chrome dev tools when
there's nothing we can do about it.
So I'll ignore that one.
And I'm not seeing the network request going to go out and get the address, which we then use to populate
this.
So something is awry.
Okay, so after a bit of off screen troubleshooting, I have discovered that when it doesn't work,
then our address is being loaded after the stripe elements are being loaded.
And if I take a look at this request because I can see I'm missing the full name there, inside here
I can see I'm making the fetch request to go and get user info basket and payments.
And then we've got some stripe requests going on inside here.
And somewhere buried down here is the address.
So it's just a timing issue.
The address is getting loaded.
Or our request to go out to our API is getting loaded after the elements are being populated on the
page.
And then the way that we're using the default elements, it's not giving it a chance to go and get it.
So fairly easy fix actually inside our use fetch address query, we can just use the Isloading flag.
And we can make sure that this isn't loading before we return the stripe elements.
So I'll just go back to the checkout page and I will just copy this typography where we're loading our
checkouts.
And I'll effectively replicate that inside our stepper as well.
So before we return what's going on here I will add an if statement and say is loading.
And then we can return the typography here.
And I'll just bring in what we need for the imports.
And if we go back to the browser, what we should find now is consistently every time, no matter how
many times we refresh, we're going to see the address populate inside there because the address elements
cannot load until we have the address, or there is no address, of course.
And then it will just be the default address that we saw, or empty address that we saw when we didn't
have the address.
So that fixes that little problem.
So great.
But we didn't actually test the updating of the address.
So that's something we should do.
Let's change the country to United States.
And I'll change the address line 1 to 100 somewhere center streets in New York.
And if I click save as default address and click next, we should see loading going on.
And that should mean that our address has been updated.
So if I click back and then I refresh the page, this will force a request to go to our API.
And we would expect to see the address being persisted inside here.
And we do.
However, we've still got the possibility even if we have an invalid address of going on to the next
step.
And I would like to avoid that.
So we'll take a look at validating these inputs and checking that they're complete before allowing progress
to the next step.