1
votes

I have a case to display the question one at a time from a list of questions, with a radio button to capture the response as yes or no.

My Approach:

I am initializing a javascript object question = "{currentId : 0, questionId : 'value', question : 'This is the question text?"} in typescript code of the component.

In current Component's HTML template I have set the radio buttons with name attribute set to "question.questionId",

On click of Next button I am submitting the form and appending the data in response list which contains "[{questionId "value", response: "true/false"}]", and replacing the value of question object by increment "question.currentId" by 1 and getting data from the next element of questions list.

On submitting the next question I find that the radio button Element's name attribute value remains unchanged for the consecutive questions.

I am not able to figure out why the value is not changed in the name attribute. However, the display of question text in HTML changes for each incrementing count.

Please provide a solution to this

question.component.html:

<form class="form-horizontal" (ngSubmit)=onSubmit() #questionForm='ngForm'>
          <div class="card-body">
              <label class="col-md-12 col-form-label">{{ question.question1 }}</label>
            <div class="form-group row">

              <div class="col-md-9 col-form-label">
                <div class="form-check">
                  <input class="form-check-input" type="radio" name= "question{{ question.questionId }}"  value="true" ngModel>
                  <label class="form-check-label" for="radio1">
                    Yes
                  </label>
                </div>
                <div class="form-check">
                  <input class="form-check-input" type="radio" name= "question{{ question.questionId }}"  value="false" ngModel [ngModel] = "checked">
                  <label class="form-check-label" for="radio2">
                    No
                  </label>
                </div>
              </div>
            </div>
          </div>
          <div class="card-footer">
            <button type="button" class="btn btn-sm btn-success" (click) = "onPrevious()" [disabled] = "question.currentId === 0">
              <i class="fa fa-arrow-left"></i> Previous</button>
              &nbsp;
            <button type="submit" class="btn btn-sm btn-success" [disabled] = "question.currentId === questions.length">
              <i class="fa fa-arrow-right"></i> Next</button>
            <button type="button" class="btn btn-sm btn-success" style="float: right;" (click) = "submitComponentResponses()">
              <i class="fa fa-ban"></i> Submit</button>
          </div>
        </form>

question.component.ts:

private getComponentAndQuestions() {

    this.questionService.getQuestionsData(projectAssessmentId).subscribe(q => {
      this.questions = q;
      this.question = {
        currentId: 0,
        questionId: this.questions[0].questionId,
        question1: this.questions[0].question1,
        quizId: this.questions[0].quizId
      }
    }, error => {
      this.exceptionService.errorHandler(error);
    });

  }

  onSubmit() {
    if (this.questionForm.valid) {
      let UserProjectId = this.userProject.id;
      Object.keys(this.questionForm.form.controls).forEach(
        (key) => {
          if (this.response.some((item) => item.QuesId == key)) {
            this.response.splice(this.question.currentId, 1, {
              QuesId: key,
              Response: this.questionForm.form.get(key).value,
              UserProjectId: this.userProject.id
            });
          } else {
            this.response.push({
              QuesId: key,
              Response: this.questionForm.form.get(key).value,
              UserProjectId: UserProjectId
            });
          }
        }
      );

      //Increment the current Id and reset question object to next element 
      //from array of questions.
       if (this.question.currentId < this.questions.length - 1) {
         this.setCurrentQuestion(this.question.currentId + 1);
       }
    }
  }

 private setCurrentQuestion(currId: number) {
    this.question = {
      currentId: currId,
      questionId: this.questions[currId].questionId,
      question1: this.questions[currId].question1,
      quizId: this.questions[currId].quizId
    }
  }
1
Whether the label here changed or it also remains same?? <label class="col-md-12 col-form-label">{{ question.question1 }}</label> - Maniraj Murugan
Yes the label changed with next question text. - NITESH SHARMA
I have inspected the html element for this and can see the update value of name attribute. But maybe since the component is not reloaded the form maintains its state and do not provide the updated value to typescript code on Submit - NITESH SHARMA

1 Answers

0
votes

Try setting the name property angular way:

[name]="'question' + question.questionId" or 
[attr.name]="'question' + question.questionId"