Non
Non

Reputation: 8589

How can I filter an array by multiple conditions but keeping its current state?

I am trying to work on a filter functionality where I have 4 different filters and I need to have the option to combine them.

This is the data sample:

[
  {
    uniqueId: 23,
    status: false,
    employeeRole: true,
  },
  {
    uniqueId: 35,
    status: true,
    employeeRole: true,
  },
  {
    uniqueId: 9,
    status: true,
    employeeRole: false,
  }
]

The filters are: If the status false === 'inactive' || true === 'active' and the same for the employeeRole true === 'APA' || false === 'employee'.

The filter works only in one scenario. If I want to filter only by status or only by employeeRole it works but if I want both then one of the filters take over the other.

handleTableFilters = dataArray => {
    const { isActive, isAPA, isInactive, isEmployee } = this.props;

    const newArr = dataArray
      ? dataArray.filter(item => {
          if (isActive || isAPA || isInactive || isEmployee) {
            return (
              (isActive === true && item.statusDetail === true) ||
              (isInactive === true && item.statusDetail === false) ||
              (isAPA === true && item.employeeRole === true) ||
              (isEmployee === true && item.employeeRole === false)
            );
          }

          return item;
        })
      : [];

    return newArr;
};

These 4 props isActive, isAPA, isInactive, isEmployee are only flags, like in a checkbox, if I check the checkbox for status filter then it sets isActive = true.

This is one scenario where it doesn't work: 1 - Set filter to show only the status === true (it shows only status true as expected).

2 - Also set filter to show employeeRole === true (it shows all of the employeeRole === true ignoring that the status filter was set to show status === true).

So in the scenario the filters should work together. Only status === true + employeeRole == true.

Upvotes: 0

Views: 74

Answers (2)

HMR
HMR

Reputation: 39280

The following code should work, it sets a filters array with the values, what prop to check and what value the prop should be. Then it filters all false or undefined values out of filters.

Then, if any filter is true it will filter dataArray reducing the filters array to true or false for each item.

//set default value for dataArray
const handleTableFilters = (dataArray=[]) => {
  const {
    isActive,
    isAPA,
    isInactive,
    isEmployee,
  } = this.props;
  const filters = [
    [isActive, 'statusDetail', true],
    [isInactive, 'statusDetail', false],
    [isAPA, 'employeeRole', true],
    [isEmployee, 'employeeRole', false],
  ].filter(([val]) => val); //remove any where value is false or undefined
  //do not even filter if all are false
  if (filters.length) {
    return dataArray.filter(item =>
      filters.reduce(
        (result, [, prop, value]) =>
          result && item[prop] === value,
        true
      )
    );
  }
  return dataArray;
};

Upvotes: 1

Medet Tleukabiluly
Medet Tleukabiluly

Reputation: 11930

Don't write such code, its very annoying to fix and unreadable, separate it

handleTableFilters = dataArray => {
    const { isActive, isAPA, isInactive, isEmployee } = this.props;

    const activeFilter = item => item.statusDetail === isActive
    const APAFilter = item => item.employeeRole === isAPA


    return dataArray.filter(activeFilter).filter(APAFilter)
};

Upvotes: 2

Related Questions