Estoy creando una funcionalidad de búsqueda para divertirme usando react y tengo la siguiente estructura de datos:
export const data = [ { "id": 1, "first_name": "James", "last_name": "Wattson", "gender": "M", "age": 43, "country": "USA", }, ... const App = () => { const [query, setQuery] = useState(""); const filterKeys = ["first_name", "last_name", "gender", "age", "country"] const handleOnChange = (event) => { const filterQuery = data.filter(value => value.first_name.toLowerCase().includes(event.target.value)) setQuery(filterQuery); } const tableResults = query.length > 0 ? query : data; return ( <div className="form"> <div> <input placeholder="search..." onChange={handleOnChange}/> </div> <div> <Table data={tableResults}/> </div> </div> ); }; export default AppMi funcionalidad de búsqueda funciona bien, pero solo está limitada en los datos de nombre como entrada.
¿Cómo puedo actualizar la lógica de la variable const filterQuery usando el .some() array method para poder agregar filtros basados en las cadenas filterKeys de la matriz, que son claves adicionales que podría buscar por sus valores?
Objetivo: poder buscar los valores de cada clave, incluidos: nombre, apellido, género, edad, país. los códigos anteriores solo pueden buscar valores de first_name
algo como esto
const filterQuery = data.filter(value => filterKeys.some(key => value[key].toLowerCase().includes(event.target.value))); pero esto no parece ser correcto... porque se bloquea en la pestaña de la consola de Chrome mientras se escribe. el error Uncaught TypeError: value[key].toLowerCase is not a function
A veces obtienes typeof value[key] Number, Number no tiene método toLowerCase() , por lo que necesitas usar:
const filterQuery = data.filter(value => filterKeys.some(key => (value[key] + "").toLowerCase().includes(event.target.value)));Si obtiene este error:
value[key].toLowerCase no es una función
...significa que value[key] no es una cadena (¿quizás null o undefined o numérico?). Este es el caso de la propiedad "edad", ya que parece ser numérica. Para manejar esta situación silenciosamente, encadene una llamada a .toString y haga que todas las búsquedas de propiedades sean condicionales, usando el operador de encadenamiento opcional ( ?. ):
value[key]?.toString()?.toLowerCase()?.includes(event.target.value)Tu función handleOnChange podría ser así:
Mi solución no usa ningún método de matriz, solo otra forma de obtener lo que desea (no necesita some filterKeys de filtro también)
const handleOnChange = (event) => { const term = event.target.value; const filterQuery = data.filter((record) => { return ( Object.values(record) .filter((r) => !Number.isInteger(r)) .filter((r) => r.toLowerCase().includes(term)).length > 0 ); }); setQuery(filterQuery); }; Object.values(record) devolverá todo el value del objeto de registro, después de eso, debe usar el filter para encontrar qué registro tiene value que contiene event.target.value .