buildkit-primevue
Version:
FormKit components and helpers built on PrimeVue v4 with Tailwind CSS
115 lines (93 loc) • 3.05 kB
text/typescript
import {ref, onUnmounted} from "vue";
import axios from "axios";
import type {ZipcodeResult} from "./types/ZipcodeResult.ts";
const useFormKitZipcodeSearch = () => {
const isLoading = ref(false);
let controller: AbortController | null = null;
let reqId = 0;
const search = async (zipcode: string): Promise<ZipcodeResult | null> => {
const numeric = String(zipcode)?.replace("-", "")?.trim() || "";
if (!zipcode || numeric?.length !== 7 || isNaN(parseInt(numeric))) {
return null;
}
// Cancel any in-flight request
controller?.abort?.();
controller = new AbortController();
const thisReq = ++reqId;
try {
isLoading.value = true;
const response = await axios.get('https://zipcloud.ibsnet.co.jp/api/search', {
params: {zipcode: numeric},
signal: controller.signal as any,
});
if (response.data.status === 200 && response.data.results) {
return response.data.results[0];
}
} catch (e: any) {
// Swallow abort errors silently
if (e?.name !== 'CanceledError' && e?.message !== 'canceled') {
// optional: console.debug('Zipcode search error', e)
}
} finally {
if (thisReq === reqId) {
isLoading.value = false;
}
}
return null;
};
const setFieldSafely = (form: any, field: string, value: any) => {
try {
if (typeof form?.setFieldValue === 'function') {
form.setFieldValue(field, value);
return;
}
} catch {}
try {
if (typeof form?.setValues === 'function') {
form.setValues({ [field]: value });
return;
}
} catch {}
try {
// Fallback: attempt to mutate known shapes
if (form?.states) {
// PrimeVue Form states usually has shape { [name]: { value, ... } }
if (form.states[field] && typeof form.states[field] === 'object' && 'value' in form.states[field]) {
form.states[field].value = value;
return;
}
// Or a plain map of values in our test mocks
form.states[field] = value;
return;
}
} catch {}
};
const setAddress = async (form: any) => {
// Try to read zipcode value from common shapes
const zipcode = (() => {
try {
if (typeof form?.getFieldState === 'function') {
return form.getFieldState('zipcode')?.value ?? '';
}
} catch {}
try {
return (form as any)?.zipcode?.value ?? (form as any)?.states?.zipcode?.value ?? (form as any)?.states?.zipcode ?? '';
} catch {}
return '';
})();
const result = await search(String(zipcode));
if (!result) return;
const prefecture = result.address1 ?? '';
const address = `${result.address2 || ''}${result.address3 || ''}`;
setFieldSafely(form, 'prefecture', prefecture);
setFieldSafely(form, 'address', address);
}
onUnmounted(() => {
controller?.abort?.();
});
return {
isLoading,
setAddress,
};
};
export default useFormKitZipcodeSearch;