I am struggling to filter an array in one of my react projects.
My React App has a search bar that returns a searchQuery as a string and menu of movement patterns that when clicked gets added to the pattern array. The user should be able to:
const searchQuery = "ben"; const pattern = []; const exercises = [ { name: "bench press", movement: ["push", "pull", "squat", "hinge"] }, { name: "squat", movement: ["push", "pull", "squat", "hinge"] }, { name: "squat", movement: ["squat", "hinge"] }, { name: "pushup", movement: ["push", "pull", "squat", "hinge"] }, { name: "pullup", movement: ["pull", "squat", "hinge"] }, { name: "bent over row", movement: ["push", "pull", "hinge"] } ]; let filteredExercises = []; if (searchQuery && pattern) { filteredExercises = exercises.filter( exercise => exercise.name.toLowerCase().indexOf(searchQuery) !== -1 && exercise.movement.some(movement => pattern.some(pattern => pattern == movement) ) ); } else if (pattern.length > 0) { filteredExercises = exercises.filter(exercise => exercise.movement.some(movement => pattern.some(pattern => pattern == movement) ) ); } else if (searchQuery) { filteredExercises = exercises.filter( exercise => exercise.name.toLowerCase().indexOf(searchQuery) !== -1 ); console.log(filteredExercises); } console.log(filteredExercises);
The first two conditional statements work and return the correct data. As soon as I add the third conditional statement to filter by searchQuery I get an empty array in return.
Can anyone help with this?
An empty array is truthy which means your first if
is firing when pattern
is empty — it never makes it to your last else if
. You can test for pattern.length
instead and it should work
const searchQuery = "ben"; const pattern = []; const exercises = [ { name: "bench press", movement: ["push", "pull", "squat", "hinge"] }, { name: "squat", movement: ["push", "pull", "squat", "hinge"] }, { name: "squat", movement: ["squat", "hinge"] }, { name: "pushup", movement: ["push", "pull", "squat", "hinge"] }, { name: "pullup", movement: ["pull", "squat", "hinge"] }, { name: "bent over row", movement: ["push", "pull", "hinge"] } ]; let filteredExercises = []; if (searchQuery && pattern.length) { filteredExercises = exercises.filter( exercise => exercise.name.toLowerCase().indexOf(searchQuery) !== -1 && exercise.movement.some(movement => pattern.some(pattern => pattern == movement) ) ); } else if (pattern.length > 0) { filteredExercises = exercises.filter(exercise => exercise.movement.some(movement => pattern.some(pattern => pattern == movement) ) ); } else if (searchQuery) { filteredExercises = exercises.filter( exercise => exercise.name.toLowerCase().indexOf(searchQuery) !== -1 ); console.log(filteredExercises); } console.log(filteredExercises);
I think checking the array as a truthy value instead of the length of the array was your biggest issue.
However, I also think this could be written more simply by moving the repeated code to functions and just running one filter
. If you don't like ternary operators you can replace what I have with your if
/ if else
clauses (don't forget the returns though).
const searchQuery = "ben"; const pattern = []; const exercises = [ { name: "bench press", movement: ["push", "pull", "squat", "hinge"] }, { name: "squat", movement: ["push", "pull", "squat", "hinge"] }, { name: "squat", movement: ["squat", "hinge"] }, { name: "pushup", movement: ["push", "pull", "squat", "hinge"] }, { name: "pullup", movement: ["pull", "squat", "hinge"] }, { name: "bent over row", movement: ["push", "pull", "hinge"] } ]; const excerciseTest = (name, searchQuery) => { return name.toLowerCase().includes(searchQuery.toLowerCase()) } const patternTest = (movement, pattern) => { return movement.some(movement => { return pattern.some(pattern => pattern === movement) }) } const filteredExercises = exercises.filter(excercise => { // if (searchQuery && pattern.length > 0) return (searchQuery && pattern.length > 0) ? excerciseTest(excercise.name, searchQuery) && patternTest(excercise.movement, pattern) // else if (pattern.length > 0) : pattern.length > 0 ? patternTest(excercise.movement, pattern) // else if (searchQuery) : searchQuery ? excerciseTest(excercise.name, searchQuery) : false }) console.log(filteredExercises)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.