I am trying to create a survey with yes/no question, I will have many questions, so I'd like to create an array with all the info and then run ngFor
to display my questions.
It works perfectly. What I'd like to do now is to add a parameters to each of my question that allow me to specify if this question will be displayed depending on the answer of others questions. So in the array that followed, I'd like to add something into the condition of question id 1 like 'questions.id.answer == 'YES''
, I know that this does not work questions.id.answer can not work but I think you gt the idea.
questions = [
{
id:0,
title: "Test 1 ?",
answer: "",
condition: ""
},
{
id: 1,
title: "Test 2 ?",
answer: "",
condition: ""
},
{
id: 2,
title: "Test 3 ?",
answer: "",
condition:""
},
];
Here is my hmtl file :
<ion-list *ngFor="let q of questions; let i = index">
<ion-list-header>
<ion-label id="sous_sous_titre" class='ion-text-center'>
Q{{i}} - {{q.title}}
</ion-label>
</ion-list-header>
<ion-radio-group
(ionChange)="SelectedType($event,q.id)"
([ngModel])="q.answer"
name="q.answer"
>
<ion-item >
<ion-label>YES</ion-label>
<ion-radio value="yes"></ion-radio>
</ion-item>
<ion-item >
<ion-label>NO</ion-label>
<ion-radio value="no"></ion-radio>
</ion-item>
</ion-radio-group>
</ion-list>
<ion-button (click)="onValidate()">Valider</ion-button>
and here my function in my .ts file :
SelectedType(event, id:number){
console.log(id);
this.questions[id].answer = event.detail.value;
}
onValidate(){
console.log(this.questions);
}
So basically, I'd like to add somewhere a *NgIf=""
and inside this I could pass q.condition
, but I have no idea what to put in the condition
.
I'd like to access the answer of a question with maybe something like q[i].answer == 'YES'
, but it does not work ...
I would solve this problem by applying these steps:
Step 1: I would use the following structure, the only difference is to use a boolean property is_visible
instead of condition
, I would say that I want to show all the questions except for the third one, that question will be visible when a specific business condition is evaluated to true, let that be "Answering the first question with YES"
questions = [
{
id:0,
title: "Test 1 ?",
answer: "",
is_visible: true //instead of using a condition, I will use a boolean parameter
},
{
id: 1,
title: "Test 2 ?",
answer: "",
is_visible: true
},
{
id: 2,
title: "Test 3 ?",
answer: "",
is_visible: false
},
];
Step 2: I will render the above questions array into HTML view just the way you did, except for always checking for the is_visible property.. I will use the property to show or hide the question:
<ion-list *ngFor="let q of questions; let i = index">
<ng-container *ngIf="q.is_visible"> // This is the only difference here, the question will be rendered only if it's own is_visible equals to true
<ion-list-header>
<ion-label id="sous_sous_titre" class='ion-text-center'>
Q{{i}} - {{q.title}}
</ion-label>
</ion-list-header>
<ion-radio-group
(ionChange)="SelectedType($event,q.id)"
([ngModel])="q.answer"
name="q.answer"
>
<ion-item >
<ion-label>YES</ion-label>
<ion-radio value="yes"></ion-radio>
</ion-item>
<ion-item >
<ion-label>NO</ion-label>
<ion-radio value="no"></ion-radio>
</ion-item>
</ion-radio-group>
</ng-container>
</ion-list>
<ion-button (click)="onValidate()">Valider</ion-button>
Step3: Now, when the end-user answers any question, the SelectedType
method will be executed, I would discuss the logic of hiding and showing other questions here:
SelectedType(event, id:number){
console.log(id);
this.questions[id].answer = event.detail.value;
// Hide the third question if the first question is Yes.
switch (id) {
case 0: // this is the first question
if(this.questions[id].answer == 'Yes') // Show the third question
this.questions[2].is_visible = true;
else // Hidethe third question incase the user changed his mind ;)
this.questions[2].is_visible = false;
break;
default:
break;
}
}
Then Angular will automatically detect the changes that have been accrued to the questions array, as a result the third question will be shown or hidden according to user answer. it's always easier to put the conditions logic into the typescript and letting your view act according to the result of evaluating the complex condition.
If that helped you, please mark it as correct and up-vote it. All the best!