Skip to content Skip to sidebar Skip to footer

Identifying What Item Have Been Deleted (created And Modifed) In A Formik Fieldarray

Was wondering if Formik has a native solution for identifying the addition and deletion (and update) of FieldArray in the form ? I have the code on sandbox here https://codesandbox

Solution 1:

Its not built into Formik, but it is not hard to do in javascript.

First, understand that Formik clones the object you give to initialValues. So in onSubmit, you will compare the final value to your original object.

The incoming data:

const initialFriends = [
  {
    name: "Friend_A",
    email: "email_A@somewhere.com"
  },
  {
    name: "Friend_B",
    email: "email_B@somewhere.com"
  },
  {
    name: "Friend_C",
    email: "email_C@somewhere.com"
  }
];

const initialValues = { friends: initialFriends };

Modified Formik declaration:

<Formik initialValues={initialValues}
  ...
  onSubmit={values => {
    const { added, deleted, changed } = addDeleteChange(
      initialFriends,
      values.friends
    );

    setTimeout(() => {
      alert(
        "Added: " + JSON.stringify(Object.fromEntries(added.entries()))
      );
      alert(
        "Deleted: " + JSON.stringify(Object.fromEntries(deleted.entries()))
      );
      alert(
        "Changed:" + JSON.stringify(Object.fromEntries(changed.entries()))
      );
      alert(JSON.stringify(values, null, 2));
    }, 500);
  }}
  ...

Helper functions:

functionpartition(array, filter) {
  let pass = [],
    fail = [];
  array.forEach(e => (filter(e) ? pass : fail).push(e));
  return [pass, fail];
}

constaddDeleteChange = (in1, out1) => {
  let inMap = newMap(in1.map(f => [f.name, f]));
  let outMap = newMap(out1.map(f => [f.name, f]));
  let inNames = newSet(inMap.keys());
  let outNames = newSet(outMap.keys());
  let [kept, added] = partition(out1, f => inNames.has(f.name));
  let deleted = in1.filter(f => !outNames.has(f.name));
  //alert(JSON.stringify(Object.fromEntries(deleted.entries())));let changed = kept.filter(f => f.email !== inMap.get(f.name).email);
  //alert(JSON.stringify(Object.fromEntries(changed.entries())));return { added: added, deleted: deleted, changed: changed };
};

Code in codesandbox


NOTE: If you change the name of a friend, that will appear as a delete of original friend and an add of a new friend. A more robust solution would be to add a (hidden) "id" field to each friend. Then instead of comparing name, would compare id. That requires generating a new id as add each friend.

Post a Comment for "Identifying What Item Have Been Deleted (created And Modifed) In A Formik Fieldarray"