Reputation: 63
I am working on a filter for an e-commerce project.
It has an active filters section, where the filters that are active are displayed and can be made inactive. This function works, correctly finds the index and removes the right object. I used some of the same code to create the function that toggles a filters active status, but for some reason it just constantly returns -1 even though the console log shows the object in the array, and shows the object being exactly the same. I am so confused.
Here's the console log of the array:
[
{
"section": "Section 1",
"option": "Option 1"
},
{
"section": "Filter Section",
"option": "Option 1"
},
{
"section": "Section 1",
"option": "Option 2"
}
]
Here's the console log of the object i am trying to find the index of:
{
"section": "Filter Section",
"option": "Option 1"
}
And then the console is logging -1 for the index, when it should clearly be 1.
Here's the code:
import styles from '../../styles/SASS/filter.module.scss';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faPlus, faMinus, faTimes, faCheck } from '@fortawesome/free-solid-svg-icons'
import { useState } from 'react';
export default function Filter(params) {
// hard coded data for dev purposes
let myFilters = {sections: [
{name: "Filter Section", options: ["Option 1", "Option 2", "Option 3"]}
]
};
let [activeFilters, setActiveFilters] = useState([{section: "Section 1", option: "Option 1"},
{section: "Filter Section", option: "Option 1"},
{section: "Section 1", option: "Option 2"}
]);
let [filters, setFilters] = useState(myFilters);
let [openSections, setOpenSections] = useState(["Active Filters"]);
let isActive = (string) => {
let section = string.split(":")[0];
let option = string.split(":")[1];
let filter = {};
filter.section = section;
filter.option = option;
let currentActiveFilters = [...activeFilters];
let index = currentActiveFilters.findIndex(activefilter => activefilter == filter);
// console.log(currentActiveFilters);
// console.log(filter)
// console.log(`Index is ${index}`)
if (index !== -1) {
return true;
} else {
return false;
}
}
let removeActiveFilter = (filter) => {
let currentActiveFilters = [...activeFilters];
let index = currentActiveFilters.findIndex((activefilter) => {
activefilter == filter;
});
currentActiveFilters.splice(index, 1);
setActiveFilters(currentActiveFilters);
}
let toggleActive = (string) => {
let section = string.split(":")[0];
let option = string.split(":")[1];
let filter = {};
filter.section = section;
filter.option = option;
let currentActiveFilters = [...activeFilters];
let index = currentActiveFilters.findIndex((activefilter) => {
// console.log(activefilter);
// console.log(filter);
// activefilter == filter;
activefilter.section == filter.section && activefilter.option == filter.option
});
if (index > 0) {
currentActiveFilters.splice(index, 1);
setActiveFilters(currentActiveFilters);
} else {
currentActiveFilters.push(filter);
setActiveFilters(currentActiveFilters);
}
}
let isOpen = (section) => {
let openedSections = [...openSections];
let index = openedSections.findIndex(openSection => openSection == section);
if (index !== -1) {
return true
} else {
return false
}
}
let toggleOpen = (section) => {
let openedSections = [...openSections];
let index = openSections.findIndex(openSection => openSection == section);
if (index === -1) {
openedSections.push(section);
setOpenSections(openedSections);
} else {
openedSections.splice(index, 1);
setOpenSections(openedSections);
}
}
return (
<div className={params.showFilter == true ? `${styles.overlay} ${styles.open}` : `${styles.overlay}`}>
<div className={styles.filter}>
<div className={styles.header}>
<p className={styles.title}>Filters</p>
</div>
<div className={styles.activeFilters}>
<div className={styles.sectionHeader} onClick={() => toggleOpen('Active Filters')}>
<p>Active Filters ({activeFilters.length})</p>
{isOpen('Active Filters') ? <FontAwesomeIcon icon={faMinus} className={styles.icon}/> : <FontAwesomeIcon icon={faPlus} className={styles.icon}/>}
</div>
<div className={activeFilters.length > 0 && isOpen('Active Filters') || isOpen('Active Filters') ? `${styles.sectionContent} ${styles.open}`: `${styles.sectionContent}`}>
{activeFilters.length < 1 ? <p className={styles.message}>You haven't applied any filters yet.</p> : <></>}
<div className={styles.filtersContainer}>
{activeFilters.map((filter) => {
return (
<div key={`${filter.section}:${filter.option}`} className={styles.activeFilter}>
<p>{filter.section}: </p>
<p>{filter.option}</p>
<FontAwesomeIcon icon={faTimes} className={styles.removeIcon} onClick={() => removeActiveFilter(filter)}/>
</div>
)
})}
</div>
</div>
</div>
{filters.sections.map((filter) => {
return (
<div key={filter.name} className={styles.filterSection}>
<div className={styles.sectionHeader} onClick={() => toggleOpen(filter.name)}>
<p>{filter.name}</p>
{isOpen(filter.name) ? <FontAwesomeIcon icon={faMinus} className={styles.icon}/> : <FontAwesomeIcon icon={faPlus} className={styles.icon}/>}
</div>
<div className={isOpen(filter.name) ? `${styles.sectionContent} ${styles.open}`: `${styles.sectionContent}`}>
{filter.options.map((option) => {
return (
<div key={`option:${filter.name}:${option}`}
className={isActive(`${filter.name}:${option}`) ? `${styles.filterChoice} ${styles.active}` : `${styles.filterChoice}`}
onClick={() => toggleActive(`${filter.name}:${option}`)}>
<div className={styles.checkbox}>
<FontAwesomeIcon icon={faCheck} className={styles.checkmark} />
</div>
<p className={styles.label}>{option}</p>
</div>
)
})}
</div>
</div>
)
})}
<div className={styles.footer}>
<button className={styles.resetBtn} onClick={() => setActiveFilters([])}>Reset Filters</button>
<button className={styles.closeBtn} onClick={() => params.setShowFilter(false)}>Close</button>
</div>
</div>
</div>
)
};
Upvotes: 0
Views: 493
Reputation: 3026
As explained in the comments, you can't compare objects are equal, unless they reference the same variable. There are some approaches to deep object comparison in this question.
However, a common approach is to add a unique identifier to your objects array. Then you can findIndex
of the object matching the same identifier.
[
{
"id": "filter1",
"section": "Section 1",
"option": "Option 1"
},
{
"id": "filter2",
"section": "Filter Section",
"option": "Option 1"
},
{
"id": "filter3",
"section": "Section 1",
"option": "Option 2"
}
]
currentActiveFilters.findIndex(activefilter => activefilter.id === filter.id);
Upvotes: 1