Basically I have a form with question and an input field for the answer like on the screenshot below.
How do I get the question id and answer as an array of objects using formcontrol the same structure on the expected output below.
The answer from the object is the answer from each text area fields and the qid is the qid from the questions. Any idea would be much appreciated. Thanks.
#html code
<form *ngIf="modelForm" [formGroup]="modelForm">
<div *ngFor="let q of questions;let i = index;" >
<div >
<div >{{q.question}}</div>
</div>
<mat-form-field appearance="fill" style="padding-bottom:10px;">
<mat-label>Details</mat-label>
<textarea formControlName="questionAnswer" matInput matInput></textarea>
</mat-form-field>
</div>
</form>
#list of questions I am looping
const questions = [
{
"qid": 1,
"question": "What is my name ?"
},
{
"qid": 10,
"question": "Where do I live?"
}
]
#tscode
ngOnInit(): void {
this.modelForm = this._createModelForm();
}
private _createModelForm(): FormGroup {
return this.formBuilder.group({
accountId:this.model.accountId,
questions:[this.model.questions || []],
questionAnswer:[this.model.questionAnswer || []],
});
}
#expected output - the this.modelform.value , this should be the data structure after the user add answer to each field.The answer from the object is the answer from each text area fields and the qid is the qid from the questions.
{
"questionAnswer": [{
"qid" :1,
"answer" :"Josh"
},
{
"qid" :10,
"anwer" :"New York"
}],
}
CodePudding user response:
#expected output - the this.modelform.value , this should be the data structure after the user add answer to each field.The answer from the object is the answer from each text area fields and the qid is the qid from the questions.
I don't think it's possible to build the answer model like this using FormBuilder
without involving object transformation.
For your case, what I'd do:
- Convert
questions
toFormBuilder
object - Convert form value to
questionAnswer
questions = [
{
qid: 1,
question: 'What is my name?',
},
{
qid: 10,
question: 'Where do I live?',
},
];
/**
* Created mapping qid to answer
*/
private _createModelForm(): FormGroup {
const idToAnswerMap = this.questions.reduce((acc, question) => {
return {
...acc,
[question.qid]: '', // default answer is blank
};
}, {});
return this.formBuilder.group(idToAnswerMap);
}
After filling the form, if I execute this.modelForm.value
, I'd get below
{1: "answer 1", 10: "answer 2"}
// 1 is qid for question 1, 10 is qid for question 2, etc
From this, construct the object for questionAnswer
const formValues = this.modelForm.value;
const finalAnswer = {
questionAnswer: Object.keys(formValues).map((qid) => ({
qid: Number(qid),
answer: formValues[qid],
})),
};
console.log(finalAnswer)
I'd get the same result you wish
{
"questionAnswer": [
{ "qid": 1, "answer": "answer 1" },
{ "qid": 10, "answer": "answer 2" }
]
}
Here check out my Stackblitz