Search code examples
angularangular7angular-reactive-formsdynamic-formsform-control

how to make dynamic form from API response in angular 7?


I'm working on dynamic form in angular 7. I have followed the way which is mentioned on angular official website. I successfully implemented that tutorial but my scenario is different. what kind of input will be there in form and all its attribute will come from a API response

this is the function in service which brings my data. Please note: On the basis of API data i will populate my questions array, for now i used dummy data just to make sure flow is working. this is how my question.service.ts looks like

public response : QuestionBase<any>[] =[];      
getQuestions(id) {
  this.http.get(this.url+'selectAllFieldDetails/'+id)
.pipe(map(
( response: Response) => {
    let data = response;
    console.log(data);


   let questions: QuestionBase<any>[] = [

      new DropdownQuestion({
        key: 'brave',
        label: 'Bravery Ratings',
        class:'form-control fis-form-control',
        formclass:'',
        options: [
          {key: 'solid',  value: 'Solid'},
          {key: 'great',  value: 'Great'},
          {key: 'good',   value: 'Good'},
          {key: 'unproven', value: 'Unproven'}
        ],
        required: true,
        order: 2
      }),

      new TextboxQuestion({
        key: 'process',
        label: 'Process name',
        value: 'IT ',
        class:'form-control fis-form-control',
        formclass:'',
        required: true,
        order: 1
      }),


    ];
    this.response =  questions.sort((a, b) => a.order - b.order);
   }
  ));
  console.log(this.response);
  return this.response;
}

But problem is function return before the API response and it return empty array. This is the way i'm calling from create-ticket.component.ts

ngOnInit() {
  this.questions = this.service.getQuestions(24);
  console.log(this.questions);
}

Somehow i tried to get the API response first and store it in some variable and then calling this function this.service.getQuestions(24); but then it shows error that

Error: Cannot find control with name: 'process'
at _throwError (forms.js:1775)
at setUpControl (forms.js:1683)
at FormGroupDirective.push../node_modules/@angular/forms/fesm5/forms.js.FormGroupDirective.addControl (forms.js:4532)
at FormControlName.push../node_modules/@angular/forms/fesm5/forms.js.FormControlName._setUpControl (forms.js:5030)
at FormControlName.push../node_modules/@angular/forms/fesm5/forms.js.FormControlName.ngOnChanges (forms.js:4980)
at checkAndUpdateDirectiveInline (core.js:9239)
at checkAndUpdateNodeInline (core.js:10507)
at checkAndUpdateNode (core.js:10469)
at debugCheckAndUpdateNode (core.js:11102)
at debugCheckDirectivesFn (core.js:11062)

and Formgorup data remains empty. Please help me in this problem. Thanks in advance


Solution

  • So finally after a long r&d I have done this. basically there was two problem

    1. function in service respond before the API response
    2. form get created before the data come into business

    So for first issue i used the concept of async await feature in angular

    In the create-ticket.component.ts we added async and await like this.

    async ngOnInit() {
        this.questions = await this.service.getQuestionss(24);
        if(this.questions.length>0){
           this.showForm=true;
        }
    }
    

    and in service we return a promise

    async getQuestionss(id): Promise<any> {
         this.responses = await this.apiServce.getAllInputFields(id).toPromise();
    }
    

    it responds as a promise so it wait till the api response. this.apiservice.getAllInputFields(id) is just a http api call from server.

    For 2nd problem i used just a small solution. i added *ngIf in form so when the api respond with data then only form start to build.

    <app-dynamic-forms *ngIf="showForm" [questions]="questions"></app-dynamic-forms>
    

    Thats all and problem resolved.