Home > database >  Want to create a common method inside map function in react
Want to create a common method inside map function in react

Time:01-16

Below is my code

const newState = permissionData.map(obj => {
      if (obj.component.includes('Client')) {
        if ((permissionName.includes('Client')) && (name.includes('create'))) {
          return { ...obj, createPermission: event.target.checked ? 1 : 0 };
        }
        if ((permissionName.includes('Client')) && (name.includes('view'))) {
          return { ...obj, viewPermission: event.target.checked ? 1 : 0 };
        }
        if ((permissionName.includes('Client')) && (name.includes('delete'))) {
          return { ...obj, deletePermission: event.target.checked ? 1 : 0 };
        }
        if ((permissionName.includes('Client')) && (name.includes('update'))) {
          return { ...obj, updatePermission: event.target.checked ? 1 : 0 };
        }
      }

      if (obj.component.includes('Project')) {
        if ((permissionName.includes('Project')) && (name.includes('create'))) {
          return { ...obj, createPermission: event.target.checked ? 1 : 0 };
        }
        if ((permissionName.includes('Project')) && (name.includes('view'))) {
          return { ...obj, viewPermission: event.target.checked ? 1 : 0 };
        }
        if ((permissionName.includes('Project')) && (name.includes('delete'))) {
          return { ...obj, deletePermission: event.target.checked ? 1 : 0 };
        }
        if ((permissionName.includes('Project')) && (name.includes('update'))) {
          return { ...obj, updatePermission: event.target.checked ? 1 : 0 };
        }
      }

      if (obj.component.includes('Schema')) {
        if ((permissionName.includes('Schema')) && (name.includes('create'))) {
          return { ...obj, createPermission: event.target.checked ? 1 : 0 };
        }
        if ((permissionName.includes('Schema')) && (name.includes('view'))) {
          return { ...obj, viewPermission: event.target.checked ? 1 : 0 };
        }
        if ((permissionName.includes('Schema')) && (name.includes('delete'))) {
          return { ...obj, deletePermission: event.target.checked ? 1 : 0 };
        }
        if ((permissionName.includes('Schema')) && (name.includes('update'))) {
          return { ...obj, updatePermission: event.target.checked ? 1 : 0 };
        }
      }

      if (obj.component.includes('Dataset')) {
        if ((permissionName.includes('Dataset')) && (name.includes('create'))) {
          return { ...obj, createPermission: event.target.checked ? 1 : 0 };
        }
        if ((permissionName.includes('Dataset')) && (name.includes('view'))) {
          return { ...obj, viewPermission: event.target.checked ? 1 : 0 };
        }
        if ((permissionName.includes('Dataset')) && (name.includes('delete'))) {
          return { ...obj, deletePermission: event.target.checked ? 1 : 0 };
        }
        if ((permissionName.includes('Dataset')) && (name.includes('update'))) {
          return { ...obj, updatePermission: event.target.checked ? 1 : 0 };
        }
      }
      return obj;
    });

Above code is working well, however since the code is repetitive I want to make a common method to optimize the code.

But not sure how can I do it.

I am trying something like this -

const checkPermission = (obj: object, type: string, permissionName: string, name: string, checked: boolean) => {
  if (obj.component.includes(type)) {
    if ((permissionName.includes(type)) && (name.includes('create'))) {
      return { ...obj, createPermission: checked };
    }
    if ((permissionName.includes(type)) && (name.includes('view'))) {
      return { ...obj, viewPermission: checked };
    }
    if ((permissionName.includes(type)) && (name.includes('delete'))) {
      return { ...obj, deletePermission: checked };
    }
    if ((permissionName.includes(type)) && (name.includes('update'))) {
      return { ...obj, updatePermission: checked };
    }
  }
};

And I am calling this method like this -

checkPermission(obj, 'Client', permissionName, name, event.target.checked);

But it's not working. Any pointers/ideas as how to do it.

CodePudding user response:

The ['Client', 'Project', 'Schema', 'Dataset'] strings are all used identically, so put them into an array and .find the one that matches the .includes conditions, removing one dimension of repetitiveness.

After that, the proper action can be found by similarly iterating over an array of ['create', 'view', 'delete', 'update']. With that, you can update the property on the state object with bracket notation.

const newState = permissionData.map(obj => {
    const entity = ['Client', 'Project', 'Schema', 'Dataset'].find(str => obj.component.includes(str));
    if (!entity || !permissionName.includes(entity)) {
        return obj;
    }
    const action = ['create', 'view', 'delete', 'update'].find(a => name.includes(a));
    return action
        ? { ...obj, [action   'Permission']: event.target.checked ? 1 : 0 }
        : obj;
});

If possible, you might consider a better state structure - instead of having, for example

{
  createPermission: 1
  // other possible Permission keys
}

If the object doesn't contain any keys other than Permission keys, the Permission suffix doesn't add any useful information - rename the state array variable name to include Permission, and then you no longer have to use the ugly lookup with bracket notation.

If the object can contain non-Permission keys, then consider changing it so that Permission is a sub-property. And if the Permission values can only be 0 or 1, it might be more appropriate to use booleans.

{
  // state properties...

  // and also
  permissions: {
    create: true
    // etc
  }
}

Or have an array of enabled permissions.

permissions: ['create']

Or, if only one is possible, a single string.

permissions: 'create'
  • Related