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(
|
const cartIsLoading = ! store.hasFinishedResolution(
|
||||||
'getCartData'
|
'getCartData'
|
||||||
);
|
);
|
||||||
|
|
||||||
const shippingRatesLoading = store.isCustomerDataUpdating();
|
const shippingRatesLoading = store.isCustomerDataUpdating();
|
||||||
const { receiveCart } = dispatch( storeKey );
|
const { receiveCart } = dispatch( storeKey );
|
||||||
const billingAddress = decodeValues( cartData.billingAddress );
|
const billingAddress = decodeValues( cartData.billingAddress );
|
||||||
|
|
|
@ -11,9 +11,12 @@ import {
|
||||||
pluckAddress,
|
pluckAddress,
|
||||||
pluckEmail,
|
pluckEmail,
|
||||||
} from '@woocommerce/base-utils';
|
} from '@woocommerce/base-utils';
|
||||||
import type {
|
import {
|
||||||
CartResponseBillingAddress,
|
CartResponseBillingAddress,
|
||||||
CartResponseShippingAddress,
|
CartResponseShippingAddress,
|
||||||
|
BillingAddressShippingAddress,
|
||||||
|
CartBillingAddress,
|
||||||
|
CartShippingAddress,
|
||||||
} from '@woocommerce/types';
|
} from '@woocommerce/types';
|
||||||
|
|
||||||
declare type CustomerData = {
|
declare type CustomerData = {
|
||||||
|
@ -92,6 +95,26 @@ export const useCustomerData = (): {
|
||||||
shippingAddress: initialShippingAddress,
|
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.
|
// Store values last sent to the server in a ref to avoid requests unless important fields are changed.
|
||||||
const previousCustomerData = useRef< CustomerData >( customerData );
|
const previousCustomerData = useRef< CustomerData >( customerData );
|
||||||
|
|
||||||
|
@ -146,23 +169,40 @@ export const useCustomerData = (): {
|
||||||
*/
|
*/
|
||||||
useEffect( () => {
|
useEffect( () => {
|
||||||
// Only push updates when enough fields are populated.
|
// Only push updates when enough fields are populated.
|
||||||
if (
|
const shouldUpdateBillingAddress = shouldUpdateAddressStore(
|
||||||
! shouldUpdateAddressStore(
|
|
||||||
previousCustomerData.current.billingData,
|
previousCustomerData.current.billingData,
|
||||||
debouncedCustomerData.billingData
|
debouncedCustomerData.billingData
|
||||||
) &&
|
);
|
||||||
! shouldUpdateAddressStore(
|
|
||||||
|
const shouldUpdateShippingAddress = shouldUpdateAddressStore(
|
||||||
previousCustomerData.current.shippingAddress,
|
previousCustomerData.current.shippingAddress,
|
||||||
debouncedCustomerData.shippingAddress
|
debouncedCustomerData.shippingAddress
|
||||||
)
|
);
|
||||||
) {
|
|
||||||
|
if ( ! shouldUpdateBillingAddress && ! shouldUpdateShippingAddress ) {
|
||||||
return;
|
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;
|
previousCustomerData.current = debouncedCustomerData;
|
||||||
updateCustomerData( {
|
updateCustomerData(
|
||||||
billing_address: debouncedCustomerData.billingData,
|
customerDataToUpdate as Partial< BillingAddressShippingAddress >
|
||||||
shipping_address: debouncedCustomerData.shippingAddress,
|
)
|
||||||
} )
|
|
||||||
.then( () => {
|
.then( () => {
|
||||||
removeNotice( 'checkout' );
|
removeNotice( 'checkout' );
|
||||||
} )
|
} )
|
||||||
|
|
|
@ -6,9 +6,8 @@ import type {
|
||||||
Cart,
|
Cart,
|
||||||
CartResponse,
|
CartResponse,
|
||||||
CartResponseItem,
|
CartResponseItem,
|
||||||
CartBillingAddress,
|
|
||||||
CartShippingAddress,
|
|
||||||
ExtensionCartUpdateArgs,
|
ExtensionCartUpdateArgs,
|
||||||
|
BillingAddressShippingAddress,
|
||||||
} from '@woocommerce/types';
|
} from '@woocommerce/types';
|
||||||
import { ReturnOrGeneratorYieldUnion } from '@automattic/data-stores';
|
import { ReturnOrGeneratorYieldUnion } from '@automattic/data-stores';
|
||||||
import { camelCase, mapKeys } from 'lodash';
|
import { camelCase, mapKeys } from 'lodash';
|
||||||
|
@ -463,11 +462,6 @@ export function* selectShippingRate(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
type BillingAddressShippingAddress = {
|
|
||||||
billing_address: CartBillingAddress;
|
|
||||||
shipping_address: CartShippingAddress;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the shipping and/or billing address for the customer and returns an
|
* Updates the shipping and/or billing address for the customer and returns an
|
||||||
* updated cart.
|
* updated cart.
|
||||||
|
@ -476,7 +470,7 @@ type BillingAddressShippingAddress = {
|
||||||
* billing_address and shipping_address.
|
* billing_address and shipping_address.
|
||||||
*/
|
*/
|
||||||
export function* updateCustomerData(
|
export function* updateCustomerData(
|
||||||
customerData: BillingAddressShippingAddress
|
customerData: Partial< BillingAddressShippingAddress >
|
||||||
): Generator< unknown, boolean, { response: CartResponse } > {
|
): Generator< unknown, boolean, { response: CartResponse } > {
|
||||||
yield updatingCustomerData( true );
|
yield updatingCustomerData( true );
|
||||||
|
|
||||||
|
|
|
@ -198,3 +198,8 @@ export interface ExtensionCartUpdateArgs {
|
||||||
data: Record< string, unknown >;
|
data: Record< string, unknown >;
|
||||||
namespace: string;
|
namespace: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface BillingAddressShippingAddress {
|
||||||
|
billing_address: CartBillingAddress;
|
||||||
|
shipping_address: CartShippingAddress;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue