Search code examples
reactjsredux

How can I include price filter logic in a React filter?


I am working on multi filter checkbox in react and redux. How to add extra price filter logic when:

  1. The price range is less than 250

  2. The price range is between 251 and 450

  3. The price range is greater than 450

Below is the code for the filter reducer. Tried this if else condition but the problem is if multiple checkboxes are clicked this doesn't work

case actionTypes.FILTER_PRODUCT:
      const searchParameters = data && Object.keys(Object.assign({}, ...data));
      let filterData;
      console.log('test',action.payload);
      const searchQuery = action.payload.map((val) => val.toLowerCase());
      const getItemParam = (item, parameter) =>
        (item[parameter] ?? "").toString().toLowerCase();

      if (action.payload.length === 0) {
        filterData = state.products;
      } 
      else if(action.payload.includes('0-Rs250')){
        filterData = state.products.filter((item) => {
          return item.price <= 250
        })
      }
      else if(action.payload.includes('Rs251-450')){
        data = state.products.filter((item) => {
          return item.price > 250 && item.price <= 450
        })

      }else if(action.payload.includes('Rs 450')){
        filterData = state.products.filter((item) => {
          return item.price > 450
        })
      }
      else {
        filterData = state.products.filter((item) => {
          return searchParameters.some((parameter) => {
            const itemParam = getItemParam(item, parameter);

            return searchQuery.some(
              (color) => itemParam === color)
          });
        });
      }
      console.log('test1',filterData);
      return {
        ...state,
        filteredData: filterData,
      };

Solution

  • Change the conditions from exclusive OR to inclusive OR by changing from if - else if - else to if - if - if.

    Example:

    Start with initially empty filtered result set, and for each filtering criteria filter and append the original state.products array.

    case actionTypes.FILTER_PRODUCT:
      ...
    
      let filteredData = [];
    
      ...
    
      if (action.payload.length) {
        if (action.payload.includes("0-Rs250")) {
          filteredData.push(...state.products.filter((item) => {
            return item.price <= 250;
          }));
        }
        if (action.payload.includes("Rs251-450")) {
          filteredData.push(...state.products.filter((item) => {
            return item.price > 250 && item.price <= 450;
          }));
        }
        if (action.payload.includes("Rs 450")) {
          filteredData.push(...state.products.filter((item) => {
            return item.price > 450;
          }));
        }
      } else {
        filteredData = state.products.filter(/* filter by searchParams */);
      }
    
      return {
        ...state,
        filteredData,
      };
    

    An alternative using a more inline solution:

    case actionTypes.FILTER_PRODUCT:
      ...
    
      const filteredData = state.products.filter((item) => {
        if (action.payload.length) {
          return (
            (action.payload.includes("0-Rs250") && item.price <= 250) ||
            (action.payload.includes("Rs251-450") &&
              item.price > 250 &&
              item.price <= 450) ||
            (action.payload.includes("Rs 450") && item.price > 450)
          );
        }
        return /* filter by searchParams */;
      });
    
      return {
        ...state,
        filteredData,
      };
    

    This second method retains the original order of products from the source array.