How to filter-search using a single search-bar component through all data types in an Array of Objects in React?

I called an array of objects and rendered the data in table format. I need to implement filter-search using a single search-bar component that can filter through all data types like - strings, contact numbers, email addresses, address and many more I’m fetching from the API.

[
{
id: 4,
accountDetail: {
accountStatus: "ACTIVE",
referralCode: "X1DNO8GW",
signUpRemarks: "",
adminRemarks: "",
accountStatusRemarks: "",
signUpTime: {
date: {
year: 2019,
month: 3,
day: 20
},
time: {
hour: 21,
minute: 32,
second: 2,
nano: 0
}
},
lastUpdationTime: {
date: {
year: 2019,
month: 3,
day: 20
},
time: {
hour: 21,
minute: 32,
second: 2,
nano: 0
}
}
},
name: "Narendra Modi",
phone: {
countryCode: "91",
number: 9876543210,
verified: true
},
emailId: {
address: "modi@gmail.com",
verified: false
},
address: {
street: "abc",
locality: {
id: 2,
name: "ABC",
pincode: 123021,
latLong: {
latitude: 0,
longitude: 0
},
city: {
id: 1683,
district: {
id: 55,
state: {
id: "IND-MH",
code: "MH",
name: "Maharshtra",
tin: 18,
type: "S"
},
code: "",
name: "Hinjewadi"
},
name: "Pune"
}
},
latLong: {
latitude: 0,
longitude: 0
}
},
password: "9876543210",
type: "RETAILER",
businessDetail: {
gstRegistered: false,
gstin: "",
businessName: "BJP Group",
CODLimit: 0,
creditLimit: 0
},
walletBalance: 0
},
{}
]

Here’s the code I used to search through all the names in the array of objects,

let filteredData = this.state.users.filter(user => {
      return (
        user.name
          .toLowerCase()
          .indexOf(this.state.filterUsers.toLowerCase()) !== -1
      )
    })

I need to filter through data like contact number, name, business name, email id, address and every field in the objects. How do I do this?

I think you’re after something like this…

const checkUsernameFilter = user =>(
    user.name
      .toLowerCase()
      .indexOf(this.state.filterUsers.toLowerCase()) !== -1
)

const checkBusinessFilter = user =>(
    user.businessDetail.businessName
      .toLowerCase()
      .indexOf(this.state.filterBusiness.toLowerCase()) !== -1
)

const checkWhateverElse = user=> {}

let filteredData = this.state.users.filter(user =>
    checkUsernameFilter(user) &&
    checkBusinessFilter(user) &&
    checkWhateverElse(user)
)

Since you do not really need to search all the properties in the objects (i.e. signUpTime, lastUpdationTime), but do need to search some nested properties in the objects, I suggest destructuring just the properties you want to filter on and then add the property names to an array called valuesToSearch, then iterate through these values for your filter. For simplicity’s sake, I am going to assume the user will search for a single word. You would have to modify the code to check for all the words to search for at least one of the words. Also, the code below assumes the search value has been captured in some way. For my example below, I have just created a variable that is used in the filter method.

const searchValue = "Pune";

let filteredData = jsonObj.filter(({
    name,
    phone: { number: phoneNumber },
    emailId: { address: emailAddress },
    address: {
      street,
      locality: { city: { name: cityName, district: { state: { name: stateName } }, name: districtName } },
    },
    businessDetail: { businessName }
  }) => {
  const valuesToSearch = [name, phoneNumber, cityName, stateName, districtName, businessName]
    .map(val => (''+ val).toLowerCase());
  return valuesToSearch.includes(searchValue.toLowerCase());
});

1 Like