Bagaimana cara Sultan handling Client-Side Validation? πŸ“βœ…

Β·

4 min read

Halli hallo!

Buat kalian yang ngerjain Frontend pasti ada requirement untuk buat Client-Side Validation, tujuannya demi mencegah User tidak seenak jidat masukin input yang tidak sesuai dengan kriteria aplikasi tersebut.

Notabene banyak diantara Frontend ngerjain pake Yup, apalagi ngerjainnya pake Formik, ya walopun banyak yang pake Form Hooks diluar sana tapi saya suka banget sama modulenya bikinan Jared Palmer (shout out to him for building awesome Formik)

61057426-4e5a4600-a3c3-11e9-9114-630743e05814.png

cuma yang saya pelajarin banyak diantara Frontend Engineer ngehandle Client-Side nya manual alias copy-paste padahal field_1 dan field_2 sama πŸ€¦πŸ»β€β™‚οΈ

contohnya kaya begini

import { object, string } from 'yup';

const validationSchema = object().shape({
  // ngapain harus copy-paste padahal sama πŸ€¦πŸ»β€β™‚οΈ
  field_1: string().trim().max(50).required('Mohon diisi field ini'),
  field_2: string().trim().max(50).required('Mohon diisi field ini'),
  // dan schema lainnya
})

untuk yang beda sih, oke aja! Contoh kaya email dan phoneNumber misalnya. tapi semakin banyak schema jadi terlihat menggangu. Ya gak sih?

Kepikiran ga sih, untuk maintainingnya? Apalagi di E-Commerce banyak banget tuh Form Field-nya.

"Tapi bisa dibikin dengan Reusable Validation, om!"

ya emang bisa aja sih. Tapi kalo Validasi Schema bisa dalam 1 file aja gimana? Jadi ga perlu capek lagi copy-paste schema field yang sama.

Kalau saya amati setiap Form punya unique name field. Ini kita bisa generate setiap name field nya. Simple Functionnya seperti ini:

// createSchema.ts
const createSchema = <T>(initialValues: T) => {
  const fieldNames = Object.keys(initialValues);

  return !Array.isArray(fieldNames) || fieldNames.length === 0 
    ? undefined 
    : fieldNames.reduce((acc, fieldName) => ({...acc, [fieldName]: schema(fieldName)}), {})
}


export default createSchema;

lalu bikin file schema sendiri, pake switch statement (untuk ngemudahin case yang sama dengan return yang sama). Biar ga perlu copy-paste setiap field yang validasinya sama.

// schema.ts
import { string } from 'yup';

const schema = (type: string) => {
  switch (type) {
    case 'salutation':
      return string().trim().max(50).required("Wajib diisi");
    case 'title':
      return string().trim().max(50);
    case 'firstName':
    case 'lastName':
      return string().trim().min(2).max(50).required("Wajib diisi");
    case 'phone':
    case 'telephone':
    case 'fax':
      return string().trim().matches(/\d/g).min(5).max(15);
    case 'address':
    case 'city':
    case 'country':
      return string()
        .trim()
        .matches(/^([^0-9]*)$/)
        .max(50)
        .required("Wajib diisi");
    case 'houseNumber':
      return string().trim().matches(/\d/g).required("Wajib diisi");
    case 'postcode':
      return string().trim().matches(/\d/g).length(5).required("Wajib diisi");
    case 'birthday':
      return date().dateTransform('dd.MM.yyyy').typeError("format tanggal lahir tidak benar").required("Wajib diisi");
    case 'email':
      return string().trim().email("Format email salah").max(50).required("Wajib diisi");
    case 'message':
    case 'reason':
      return string().trim().required("Wajib diisi");
    default:
      return undefined;
  }
};

export default schema;

lalu tinggal generate createSchema() di validationSchema-nya Formik saya contohkan pake useFormik():

import { useFormik } from 'formik';
import { object } from 'yup';

const initialValues =  {
    email: '',
    firstName: '',
    lastName: '',
    // dan seterusnya
  };

const formik = useFormik({
  initialValues,
  validationSchema: object().shape(createSchema(initialValues))
  onSubmit: async (values) => console.log(values)
})

kalau di Formik, ID dan name props diharuskan sama dengan fieldName agar Formik bisa mengenali fieldName apa aja yang mau di validasi.

Dan kalau ada validasi yang sama untuk key yang berbeda tinggal masukin case lagi aja, seperti contoh Phone dan Fax atau Address dan Country

itu aja dulu gimana saya validasi form tanpa copy-paste.

Terima kasih sudah membaca, silahkan tulis komentar jika ada kritik, saran dan ide masukan

Cheers from Leipzig, Germany