Skip to content
Advertisement

How to filter data using multiple values in React.JS

I have a huge set of JSON data which I consider to be pretty complex when it comes to filtering data out of it. The idea is to take inputs from the user from the District, Ward No, and Categories dropdowns and use those to filter out the data i.e (grievances, general, urgent, and service), and display their properties in the table below. So like let’s say if the selected value from the dropdown is “Grievances”, it should show all the properties from the grievances array in the table. I have tried using the filter method by taking hardcoded inputs to see if the console would print anything or not but apparently it doesn’t. I don’t think I’ll be able to move any further without support on this. Below, you will find a snippet of the dropdowns, the JSON and the code that I tried for testing.

enter image description here

P.S Please ignore the data on the table as it is only hardcoded. The picture is only to give you a basic idea of what I intend to do once I get the correct resolution for the code I have written for testing.

JSON(Please note that every district has 3 ward in total. For example, in this case, the ward is 6 which has the following arrays namely "grievance", "general", "urgent", "services")

[
    {
        "district": "Kolkata",    //There are two other district values as well
        "ward_no": [
            {
                "ward": "6",     
                "grievance": [
                    {
                        "serial_number": "0001",
                        "name": "Siddhartha Chatterjee"
                    },
                    {
                        "serial_number": "0002",
                        "name": "Sajujjo Ghosh"
                    }
                ],
                "general": [
                    {
                        "serial_number": "0003",
                        "name": "Dr. Partha Pratim Paul"
                    },
                    {
                        "serial_number": "0004",
                        "name": "Dr. Partha Pratim Paul"
                    }
                ],
                "urgent": [
                    {
                        "serial_number": "0005",
                        "name": "Ritwick Banerjee"
                    },
                    {
                        "serial_number": "0006",
                        "name": "Soumadip Banerjee"
                    }
                ],
                "services": [
                    {
                        "serial_number": "0007",
                        "name": "Tanajeet Biswas"
                    },
                    {
                        "serial_number": "0008",
                        "name": "Durba Chatterjee"
                    }
                ]
            }
        ]
    }
]

The code(The query object is to store the values received from the dropdowns dynamically. This right now is hardcoded and once I have the solution, I believe I’ll be able to manage the rest)

const Screen = () => {
    var wardNo = dummyData.map(value => value.ward_no.map(value => value.ward));
    console.log(`Ward Filter: ${wardNo}`);    //To check if all the values of ward are getting displayed
    var categorySelected = dummyData.map(value => value.types.map(value => value.category));
    console.log(`category ${category}`);     //To check if all the values of category are getting displayed
    var query = {                            
        district : "Kolkata",
        ward : "6",
        category : "Grievances"
    };
    var filteredData = dummyData.filter(value => (value.district === query.district && wardNo === query.ward && categorySelected === query.category));  //The logic I used
    console.log(`filteredData ${filteredData.length}`);    //This returns 0 stating no data got filtered at all
       
    return(
        <div>
            
        </div>
    );
}

Advertisement

Answer

First of all, I’d say your JSON data is purely structured. I mean ward_no. You have categories with the dynamic name and makes it harder to filter out data while the name ward is also there (which can be a category name as well). As a suggestion, if you have an option to modify that part like this below then consider changing it.

  {
    district: 'Kolkata',
    ward_no: [
      {
        ward: '6',
        category: 'grievance',
        data: [
          {
            serial_number: '0001',
            name: 'Siddhartha Chatterjee',
          },
          {
            serial_number: '0002',
            name: 'Sajujjo Ghosh',
          },
        ],
      },
    ],
  },

I tried to make a filter function for you based on the parameters you have defined (ward, district, category).

It filters out data based on AND comparison for example when ward, category are passed both have to match.

// Your original data but minified
const data = [{"district":"Kolkata","ward_no":[{"ward":"6","grievance":[{"serial_number":"0001","name":"Siddhartha Chatterjee"},{"serial_number":"0002","name":"Sajujjo Ghosh"}],"general":[{"serial_number":"0003","name":"Dr. Partha Pratim Paul"},{"serial_number":"0004","name":"Dr. Partha Pratim Paul"}],"urgent":[{"serial_number":"0005","name":"Ritwick Banerjee"},{"serial_number":"0006","name":"Soumadip Banerjee"}],"services":[{"serial_number":"0007","name":"Tanajeet Biswas"},{"serial_number":"0008","name":"Durba Chatterjee"}]}]}];

/**
 * @description This function is used to filter the data based on the params
 * @param {{
 *   district: string,
 *   ward: string,
 *   category: string,
 * }} filterData
 */
function myFilter(filterData) {
  return data.filter((item) => {
    const filter = {
      byDistrict: true,
      byWard: true,
      byCategory: true,
    };
    if (filterData.district) filter.byDistrict = item.district === filterData.district;
    // Even if one ward_no.ward matches the value it's true
    if (filterData.ward) filter.byWard = item.ward_no.some((wards) => wards.ward === filterData.ward); 
    if (filterData.category)
      filter.byCategory = item.ward_no.some((wards) =>
        Object.keys(wards).some((categoryName) => categoryName !== 'ward' && categoryName === filterData.category));

    return filter.byDistrict && filter.byWard && filter.byCategory;
  });
}

console.log('1st filter', myFilter({ district: 'Kolkata', ward: '6', category: 'grievance' }));
// The second wont work as the district doesn't match
console.log('2nd filter', myFilter({ district: 'Kolkata-wrong', ward: '6', category: 'grievance' }));
// If you omit the district it will ignore its value and look for only ward and category
console.log('3rd filter', myFilter({ ward: '6', category: 'grievance' }));
// Same applies here
console.log('4th filter', myFilter({ category: 'grievance' }));
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement