I am trying to get question filtering to work on my react app. The issue I am encountering the issue that the questions do not filter out. For example when I click the first question from the first box, the second box does not filter out the question. It seems something is wrong with the state but I am not entirely sure because the state seems to be set fine in the hook.
As seen in the image the question should be filtered out but it isn't
Code
const [questionVals, setQuestionVals] = useState([{value: "", label: "Choose..."}, {value: "", label: "Choose..."}, {value: "", label: "Choose..."}])
const [securityQuestions, setSecurityQuestions] = useState([{ value: "favoriteBook", label: "What is your favorite book?" },
{ value: "roadYouGrewUpOn", label: "What is the name of the road you grew up on?"},
{ value: "motherMaidenName", label: "What is your mother’s maiden name?" },
{ value: "nameOfPet", label: "What was the name of your first/current/favorite pet?"},
{ value: "firstCompany", label: "What was the first company that you worked for?"},
{ value: "meetSpouse", label: "Where did you meet your spouse?" },
{ value: "highSchoolCollege", label: "Where did you go to high school/college?" },
{ value: "favoriteFood", label: "What is your favorite food?" },
{ value: "cityBorn", label: "What city were you born in?" },
{ value: "vacationPlace", label: "Where is your favorite place to vacation?" }])
const [availableOptions, setAvailableOptions] = useState([{ value: "favoriteBook", label: "What is your favorite book?" },
{ value: "roadYouGrewUpOn", label: "What is the name of the road you grew up on?"},
{ value: "motherMaidenName", label: "What is your mother’s maiden name?" },
{ value: "nameOfPet", label: "What was the name of your first/current/favorite pet?"},
{ value: "firstCompany", label: "What was the first company that you worked for?"},
{ value: "meetSpouse", label: "Where did you meet your spouse?" },
{ value: "highSchoolCollege", label: "Where did you go to high school/college?" },
{ value: "favoriteFood", label: "What is your favorite food?" },
{ value: "cityBorn", label: "What city were you born in?" },
{ value: "vacationPlace", label: "Where is your favorite place to vacation?" }])
const handleQuestionValChange = (option, index) => {
const newQuestionVals = questionVals
newQuestionVals[index] = option
setQuestionVals(newQuestionVals)
getAvailableOptions()
console.log(newQuestionVals)
}
const getAvailableOptions = () => {
const availableOptionsLeft = securityQuestions
const newOptions = availableOptionsLeft.filter(questionOption => {
return questionVals.indexOf(questionOption) === -1
})
console.log(newOptions)
setAvailableOptions(newOptions)
}
<Form.Label htmlFor="question1">Question 1</Form.Label>
<Select
name = "filters"
placeholder = "Choose..."
value={questionVals[0]}
options= {availableOptions}
onChange={(e) => handleQuestionValChange(e, 0)}
required
>
</Select>
<div class="mt-3"></div>
<Form.Control required id="securityQuestionOne" type="securityQuestionOne" name="securityQuestionOne" placeholder="Type your answer here" onChange={(e)=>{setSecurityQuestionOneAnswer(e.target.value)}} onKeyUp={changeButtonColor} ></Form.Control>
<div class="mt-3"></div>
<Form.Label htmlFor="question2">Question 2</Form.Label>
<Select
name = "filters"
placeholder = "Choose..."
value={questionVals[1]}
options= {availableOptions}
onChange={(e) => handleQuestionValChange(e, 1)}
required
>
</Select>
<div class="mt-3"></div>
<Form.Control required id="securityQuestionTwo" type="securityQuestionTwo" name="securityQuestionTwo" placeholder="Type your answer here" onChange={(e)=>{setSecurityQuestionTwoAnswer(e.target.value)}} onKeyUp={changeButtonColor} ></Form.Control>
<div class = "mt-3"></div>
<Form.Label htmlFor="question3">Question 3</Form.Label>
<Select
name = "filters"
placeholder = "Choose..."
value={questionVals[2]}
options= {availableOptions}
onChange={(e) => handleQuestionValChange(e, 2)}
required
>
</Select>
<div class="mt-3"></div>
<Form.Control required id="securityQuestionThree" type="securityQuestionThree" name="securityQuestionThree" placeholder="Type your answer here" onChange={(e)=>{setSecurityQuestionThreeAnswer(e.target.value)}} onKeyUp={changeButtonColor} ></Form.Control>
<div class="mt-5"></div>
{error &&
error.map((err, i) =>
<Alert className="mt-3" variant='danger' key={i}>{err}</Alert>
)
}
<Button size="lg" className="w-100 mb-3" type="submit" ref={signupButtonRef}>{t('signup')}</Button>
</Form>
CodePudding user response:
In getAvailableOptions
, the indexOf
you are using results in performing a Strict Equality Comparison on objects, thus comparing by reference. Since your values come from two different arrays that were instantiated separately, the references will be different for an identical question.
A possible solution is to use find
instead and to compare using the question's value
:
const newOptions = availableOptionsLeft.filter(questionOption => {
return questionVals.find(
question => question.value === questionOption.value
) === undefined;
})