Fix 'Country is required' error on the Cart block when updating shipping address (https://github.com/woocommerce/woocommerce-blocks/pull/5129)
* Fix error on the Cart block * Created a cartIsHydrated variable in useStoreCart hook and used this to update the billing address in the internal state of the useCustomerData hook * Fix the country is required error on the Cart page using refs * Separate api calls to update shipping and billingUpdate billing and shipping addresses only when needed in API calls * Remove redundant check for customerDataToUpdate * remove use of refs in initial values Co-authored-by: Nadir Seghir <nadir.seghir@gmail.com>
This commit is contained in:
parent
f9c458b090
commit
78c846bddc
|
@ -184,6 +184,7 @@ export const useStoreCart = (
|
|||
const cartIsLoading = ! store.hasFinishedResolution(
|
||||
'getCartData'
|
||||
);
|
||||
|
||||
const shippingRatesLoading = store.isCustomerDataUpdating();
|
||||
const { receiveCart } = dispatch( storeKey );
|
||||
const billingAddress = decodeValues( cartData.billingAddress );
|
||||
|
|
|
@ -11,9 +11,12 @@ import {
|
|||
pluckAddress,
|
||||
pluckEmail,
|
||||
} from '@woocommerce/base-utils';
|
||||
import type {
|
||||
import {
|
||||
CartResponseBillingAddress,
|
||||
CartResponseShippingAddress,
|
||||
BillingAddressShippingAddress,
|
||||
CartBillingAddress,
|
||||
CartShippingAddress,
|
||||
} from '@woocommerce/types';
|
||||
|
||||
declare type CustomerData = {
|
||||
|
@ -92,6 +95,26 @@ export const useCustomerData = (): {
|
|||
shippingAddress: initialShippingAddress,
|
||||
} );
|
||||
|
||||
// We only want to update the local state once, otherwise the data on the checkout page gets overwritten
|
||||
// with the initial state of the addresses here
|
||||
const [ hasCustomerDataSynced, setHasCustomerDataSynced ] = useState<
|
||||
boolean
|
||||
>( false );
|
||||
|
||||
if (
|
||||
! hasCustomerDataSynced &&
|
||||
shouldUpdateAddressStore(
|
||||
customerData.shippingAddress,
|
||||
initialShippingAddress
|
||||
)
|
||||
) {
|
||||
setCustomerData( {
|
||||
billingData: initialBillingAddress,
|
||||
shippingAddress: initialShippingAddress,
|
||||
} );
|
||||
setHasCustomerDataSynced( true );
|
||||
}
|
||||
|
||||
// Store values last sent to the server in a ref to avoid requests unless important fields are changed.
|
||||
const previousCustomerData = useRef< CustomerData >( customerData );
|
||||
|
||||
|
@ -146,23 +169,40 @@ export const useCustomerData = (): {
|
|||
*/
|
||||
useEffect( () => {
|
||||
// Only push updates when enough fields are populated.
|
||||
if (
|
||||
! shouldUpdateAddressStore(
|
||||
previousCustomerData.current.billingData,
|
||||
debouncedCustomerData.billingData
|
||||
) &&
|
||||
! shouldUpdateAddressStore(
|
||||
previousCustomerData.current.shippingAddress,
|
||||
debouncedCustomerData.shippingAddress
|
||||
)
|
||||
) {
|
||||
const shouldUpdateBillingAddress = shouldUpdateAddressStore(
|
||||
previousCustomerData.current.billingData,
|
||||
debouncedCustomerData.billingData
|
||||
);
|
||||
|
||||
const shouldUpdateShippingAddress = shouldUpdateAddressStore(
|
||||
previousCustomerData.current.shippingAddress,
|
||||
debouncedCustomerData.shippingAddress
|
||||
);
|
||||
|
||||
if ( ! shouldUpdateBillingAddress && ! shouldUpdateShippingAddress ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const customerDataToUpdate:
|
||||
| Partial< BillingAddressShippingAddress >
|
||||
| Record<
|
||||
keyof BillingAddressShippingAddress,
|
||||
CartBillingAddress | CartShippingAddress
|
||||
> = {};
|
||||
|
||||
if ( shouldUpdateBillingAddress ) {
|
||||
customerDataToUpdate.billing_address =
|
||||
debouncedCustomerData.billingData;
|
||||
}
|
||||
if ( shouldUpdateShippingAddress ) {
|
||||
customerDataToUpdate.shipping_address =
|
||||
debouncedCustomerData.shippingAddress;
|
||||
}
|
||||
|
||||
previousCustomerData.current = debouncedCustomerData;
|
||||
updateCustomerData( {
|
||||
billing_address: debouncedCustomerData.billingData,
|
||||
shipping_address: debouncedCustomerData.shippingAddress,
|
||||
} )
|
||||
updateCustomerData(
|
||||
customerDataToUpdate as Partial< BillingAddressShippingAddress >
|
||||
)
|
||||
.then( () => {
|
||||
removeNotice( 'checkout' );
|
||||
} )
|
||||
|
|
|
@ -6,9 +6,8 @@ import type {
|
|||
Cart,
|
||||
CartResponse,
|
||||
CartResponseItem,
|
||||
CartBillingAddress,
|
||||
CartShippingAddress,
|
||||
ExtensionCartUpdateArgs,
|
||||
BillingAddressShippingAddress,
|
||||
} from '@woocommerce/types';
|
||||
import { ReturnOrGeneratorYieldUnion } from '@automattic/data-stores';
|
||||
import { camelCase, mapKeys } from 'lodash';
|
||||
|
@ -463,11 +462,6 @@ export function* selectShippingRate(
|
|||
return true;
|
||||
}
|
||||
|
||||
type BillingAddressShippingAddress = {
|
||||
billing_address: CartBillingAddress;
|
||||
shipping_address: CartShippingAddress;
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the shipping and/or billing address for the customer and returns an
|
||||
* updated cart.
|
||||
|
@ -476,7 +470,7 @@ type BillingAddressShippingAddress = {
|
|||
* billing_address and shipping_address.
|
||||
*/
|
||||
export function* updateCustomerData(
|
||||
customerData: BillingAddressShippingAddress
|
||||
customerData: Partial< BillingAddressShippingAddress >
|
||||
): Generator< unknown, boolean, { response: CartResponse } > {
|
||||
yield updatingCustomerData( true );
|
||||
|
||||
|
|
|
@ -198,3 +198,8 @@ export interface ExtensionCartUpdateArgs {
|
|||
data: Record< string, unknown >;
|
||||
namespace: string;
|
||||
}
|
||||
|
||||
export interface BillingAddressShippingAddress {
|
||||
billing_address: CartBillingAddress;
|
||||
shipping_address: CartShippingAddress;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue