Reputation: 342
I'm creating a quiz app and need to toggle between mat-checkbox or mat-radio-button, depending on whether the question has one or more answers. Question #1 is a single choice answer question and shows with mat-radio-button whereas Question #2 is a multiple answer question but is also displaying with mat-radio-button instead of mat-checkbox.
This is how my template looks like:
<form [formGroup]="formGroup">
<ol *ngIf="multipleAnswer === false">
// using mat-radio-buttons here
</ol>
<ol *ngIf="multipleAnswer === true">
// using mat-checkboxes here
</ol>
</form>
and in my ts file the logic looks like:
multipleAnswer: boolean;
ngOnInit() {
this.multipleAnswer = this.quizService.getQuestionType();
}
ngOnChanges(changes: SimpleChanges) {
if (changes.question) {
switch (this.question.type) {
case 'SINGLE_CHOICE':
this.formGroup = new FormGroup({
answer: new FormControl([null, Validators.required])
});
break;
case 'MULTIPLE_CHOICE':
const multipleChoiceValidator = (control: AbstractControl) =>
control.value.reduce(
(valid: boolean, currentValue: boolean) => valid || currentValue
, false
) ? null : {answers: 'At least one answer needs to be checked!'};
this.formGroup = new FormGroup({
answers: this.formBuilder.array(this.question.shuffledAnswers
.map((answer: string) => this.formBuilder.control(false)),
multipleChoiceValidator
),
});
break;
}
}
}
don't need shuffledAnswers, question type should be inferred from the assets/quiz.ts file (shouldn't need to hard code the question type), and answers should be numbers, not strings
in my QuizService:
getQuestionType(): boolean {
return (this.correctAnswers && this.correctAnswers.length === 1);
}
Upvotes: 2
Views: 1266
Reputation: 532
There are several problems. First, calling multipleAnswer
only inside ngOnInit
sets this boolean variable only once at begining, it should be inside ngOnChanges
.
But it's not the only issue here, the main problem is in your QuizService
. Here you use this.quizService.getQuestionType();
method to set multipleAnswer
true or false but inside your getQuestionType()
method of QuizService you are checking this.correctAnswers
if set and has element length of 1 but this.correctAnswers
is always empty when you call it.
Another problem is in your ngOnChanges
you have switch (this.question.type)
here this.question
seems to be undefined evertime.
Edit your code like below and check console outputs everytime a question appears.
Add a new method the get correctAnswers
from a question.
getCorrectAnswers(question:QuizQuestion){
return question.options.filter((item)=> item.correct);
}
And edit begining of ngOnChanges like below, i also added a console output so you can see the data from the new method above.
ngOnChanges(changes: SimpleChanges) {
if (changes.question && changes.question.currentValue !== changes.question.firstChange){
this.currentQuestion = changes.question.currentValue;
this.correctAnswers = this.getCorrectAnswers(this.currentQuestion);
this.multipleAnswer = this.correctAnswers.length > 1 ? true : false;
console.log('correct ans: ', this.correctAnswers);
...
I can't modify all of the code since you have your own logic behind your code, but i updated the answer so that variables related to this problem set correctly inside 'ngOnChanges`.
Upvotes: 1