import { FormikContextType, getIn, setIn } from 'formik'; function spliceArray(arr: T[] | undefined, index: number) { const a = Array.isArray(arr) ? arr.slice() : []; if (index >= 0 && index < a.length) a.splice(index, 1); return a; } /** * Remove one item from an array field and also trim Formik's errors & touched * at the SAME index to keep everything aligned. * * @param formik - your useFormik instance * @param arrayPath - path to the array field, e.g. "kandangExpenses[0].expenses" * @param index - the index to remove * @param validateAfter - optional: revalidate after removal (default false) */ export async function removeArrayItemAndSync( formik: FormikContextType, arrayPath: string, index: number, validateAfter: boolean = false ) { // 1) VALUES: remove at index const currValues = getIn(formik.values, arrayPath); const nextValues = spliceArray(currValues, index); formik.setFieldValue(arrayPath, nextValues, false); // 2) ERRORS: remove the same index (if array exists) const currErrors = getIn(formik.errors, arrayPath); if (Array.isArray(currErrors)) { const nextErrors = spliceArray(currErrors, index); formik.setErrors(setIn(formik.errors, arrayPath, nextErrors)); } // 3) TOUCHED: remove the same index (if array exists) const currTouched = getIn(formik.touched, arrayPath); if (Array.isArray(currTouched)) { const nextTouched = spliceArray(currTouched, index); formik.setTouched(setIn(formik.touched, arrayPath, nextTouched), false); } // 4) (optional) revalidate to rebuild a perfectly clean error tree if (validateAfter) { const newErrors = await formik.validateForm(); formik.setErrors(newErrors); } }