Skip to content

Commit

Permalink
Fix address lookup reseting state after country (#2926) (#2927)
Browse files Browse the repository at this point in the history
* fixes address lookup reseting state after country

* changeset

(cherry picked from commit c5eba2a)
  • Loading branch information
m1aw authored Oct 30, 2024
1 parent 35e329a commit f52ea7f
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/cold-jeans-yawn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@adyen/adyen-web": patch
---

Fix address lookup reseting state field after country change
24 changes: 18 additions & 6 deletions packages/lib/src/components/internal/Address/Address.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ export default function Address(props: AddressProps) {

const showAddressSearch = !!props.onAddressLookup;

const [ignoreCountryChange, setIgnoreCountryChange] = useState(false);

const showAddressFields = props.onAddressLookup ? hasSelectedAddress || useManualAddress : true;

const { data, errors, valid, isValid, handleChangeFor, triggerValidation, setData } = useForm<AddressData>({
const { data, errors, valid, isValid, handleChangeFor, triggerValidation, setData, mergeData } = useForm<AddressData>({
schema: requiredFieldsSchema,
defaultData: props.data,
// Ensure any passed validation rules are merged with the default ones
Expand All @@ -52,13 +54,17 @@ export default function Address(props: AddressProps) {
const setSearchData = useCallback(
(selectedAddress: AddressData) => {
const propsKeysToProcess = ADDRESS_SCHEMA;
propsKeysToProcess.forEach(propKey => {
const newStateData = propsKeysToProcess.reduce((acc: AddressData, propKey) => {
// Make sure the data provided by the merchant is always strings
const providedValue = selectedAddress[propKey];
if (providedValue === null || providedValue === undefined) return;
// Cast everything to string
setData(propKey, String(providedValue));
});
if (providedValue !== null && providedValue !== undefined) {
// Cast everything to string
acc[propKey] = String(providedValue);
}
return acc;
}, {});
mergeData(newStateData);
setIgnoreCountryChange(true);
triggerValidation();
setHasSelectedAddress(true);
},
Expand Down Expand Up @@ -93,6 +99,12 @@ export default function Address(props: AddressProps) {
* - Applies validation on postalCode field in case it has any value
*/
useEffect((): void => {
// if the country was set via setSearchData we don't want to trigger this
if (ignoreCountryChange) {
setIgnoreCountryChange(false);
return;
}

const stateOrProvince = specifications.countryHasDataset(data.country) ? '' : FALLBACK_VALUE;
const newData = { ...data, stateOrProvince };

Expand Down
5 changes: 4 additions & 1 deletion packages/lib/src/utils/useForm/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,16 @@ export function init({ schema, defaultData, processField, fieldProblems }) {
}

export function getReducer(processField) {
return function reducer(state, { type, key, value, mode, schema, defaultData, formValue, selectedSchema, fieldProblems }: any) {
return function reducer(state, { type, key, value, mode, schema, defaultData, formValue, selectedSchema, fieldProblems, data }) {
const validationSchema: string[] = selectedSchema || state.schema;

switch (type) {
case 'setData': {
return { ...state, data: { ...state['data'], [key]: value } };
}
case 'mergeData': {
return { ...state, data: { ...state['data'], ...data } };
}
case 'setValid': {
return { ...state, valid: { ...state['valid'], [key]: value } };
}
Expand Down
1 change: 1 addition & 0 deletions packages/lib/src/utils/useForm/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export interface Form<FormSchema> extends FormState<FormSchema> {
triggerValidation: (schema?: any) => void;
setSchema: (schema: any) => void;
setData: (key: string, value: any) => void;
mergeData: (data: FormSchema) => void;
setValid: (key: string, value: any) => void;
setErrors: (key: string, value: any) => void;
mergeForm: (formValue: any) => void;
Expand Down
2 changes: 2 additions & 0 deletions packages/lib/src/utils/useForm/useForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ function useForm<FormSchema>(props: FormProps): Form<FormSchema> {
const setErrors = useCallback((key, value) => dispatch({ type: 'setErrors', key, value }), []);
const setValid = useCallback((key, value) => dispatch({ type: 'setValid', key, value }), []);
const setData = useCallback((key, value) => dispatch({ type: 'setData', key, value }), []);
const mergeData = useCallback(data => dispatch({ type: 'mergeData', data }), []);
const setSchema = useCallback(schema => dispatch({ type: 'setSchema', schema, defaultData }), [state.schema]);
const mergeForm = useCallback(formValue => dispatch({ type: 'mergeForm', formValue }), []);
const setFieldProblems = useCallback(fieldProblems => dispatch({ type: 'setFieldProblems', fieldProblems }), [state.schema]);
Expand All @@ -69,6 +70,7 @@ function useForm<FormSchema>(props: FormProps): Form<FormSchema> {
triggerValidation,
setSchema,
setData,
mergeData,
setValid,
setErrors,
isValid,
Expand Down

0 comments on commit f52ea7f

Please sign in to comment.