JS Remove Optional Input
Tags: javascript, programming, webdev, tutorial
Published: 2023-12-20 02:51:06

```js
// Example data input
    const dataInput = {
      id: '11x',
      name: 'Fruits',
      items: [
        {
          name: 'Manggo',
          types: ['busuk', 'bagus'],
          country: { name: 'nigeria' },
          weight: 0,
          others: {
            name: 'other name',
            value: 0,
          },
        },
      ],
      genus: '',
      farmers: [],
      falsyValue: '',
    };
```

```js
// Expected output
{
    id: "11x",
    name: "Fruits",
    items: [
        {
            name: "Manggo",
            country: { name: "nigeria" },
            others: { name: "other name" },
            types: ["busuk", "bagus"]
        }
    ]
}
```

Pertama, saya akan menggunakan package [flat js](https://www.npmjs.com/package/flat) untuk membuat outputnya jadi seperti ini.

```js
// example flat output
{
  id: "11x",
  name: "Fruits",
  items.0.name: "Manggo",
  items.0.types.0: "busuk",
  items.0.types.1: "bagus",
  items.0.country.name: "nigeria",
  items.0.others.name: "other name"
  // disini key-value lainnya agar tidak terlalu panjang .....
}
```

Pertimbangannya object tadi saya flat adalah agar tidak perlu membuat logika perulangan yang kompleks.

Untuk fungsinya nanti saya ingin menggunakannya seperti ini:
```js
const removeOptionalFlat = removeOptionalInput(dataInput, [
      'bejo',
      'items.*.weight',
      'items.*.country',
      'genus',
      'items.*.others.value',
      'falsyValue',
      'farmers',
    ]);
```

Untuk fungsi `removeOptionalFlat` nya seperti ini:
```js
function removeOptionalInput(dataObject, propertiesToRemove) {
  const newDataObject = { ...dataObject };

  propertiesToRemove.forEach((property) => {
    const regexPattern = new RegExp(property.replace(/\*/g, '\\d+'), 'g');
    Object.keys(newDataObject).forEach((key) => {
      if (regexPattern.test(key)) {
        if (typeof newDataObject[key] === 'object' && !Object.keys(newDataObject[key]).length) {
          delete newDataObject[key];
        }

        if (!newDataObject[key]) {
          delete newDataObject[key];
        }
      }
    });
  });

  return newDataObject;
}
```

Lihat kode fungsi `removeOptionalInput`, saya menggunakan RegEx untuk membuat asosiasi string `'items.*.country'` agar menghapus `'items.0.country'`, `'items.1.country'`, dan seterusnya. 

Karena ini merupakan fungsi yang saya peruntukan untuk menghapus input form data yang sifatnya "opsional" maka saya perlu menghapus key-value object dari dataInput yang nilainya  masuk dalam kategori _falsy_ seperti string kosong, number `0`, object/array kosong.

Fungsi yang tadi sudah dibuat hasilnya masih flat, kita perlu unflat dengan perintah `unflatten(removeOptionalFlat)`. Untuk kode secara keseluruhannya kurang lebih seperti ini.

```js
import { flatten, unflatten } from 'flat';

function removeOptionalInput(dataObject, propertiesToRemove) {
  const newDataObject = flatten({ ...dataObject });

  propertiesToRemove.forEach((property) => {
    const regexPattern = new RegExp(property.replace(/\*/g, '\\d+'), 'g');
    Object.keys(newDataObject).forEach((key) => {
      if (regexPattern.test(key)) {
        if (typeof newDataObject[key] === 'object' && !Object.keys(newDataObject[key]).length) {
          delete newDataObject[key];
        }

        if (!newDataObject[key]) {
          delete newDataObject[key];
        }
      }
    });
  });

  return unflatten(newDataObject);
}

const dataInput = {
      id: '11x',
      name: 'Fruits',
      items: [
        {
          name: 'Manggo',
          types: ['busuk', 'bagus'],
          country: { name: 'nigeria' },
          weight: 0,
          others: {
            name: 'other name',
            value: 0,
          },
        },
      ],
      genus: '',
      farmers: [],
      falsyValue: '',
    };

    const removeOptionalFlat = removeOptionalInput(dataInput, [
      'bejo',
      'items.*.weight',
      'items.*.country',
      'genus',
      'items.*.others.value',
      'falsyValue',
      'farmers',
    ]);

    console.log(removeOptionalFlat, 'remove optional flat');
```