3 votes

comment créer un formulaire dynamique à partir d'une réponse API dans angular 7 ?

Je travaille sur un formulaire dynamique en angular 7. J'ai suivi le chemin qui est mentionné sur le site officiel d'angular. J'ai réussi à mettre en œuvre ce tutoriel mais mon scénario est différent. Quel type d'entrée sera là dans le formulaire et tous ses attributs viendront d'une réponse API.

c'est la fonction en service qui apporte mes données. Veuillez noter : Sur la base des données de l'API, je vais remplir mon tableau de questions, pour l'instant j'ai utilisé des données factices juste pour m'assurer que le flux fonctionne. Voici à quoi ressemble ma question.service.ts

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;
}

Mais le problème est que la fonction retourne avant la réponse de l'API et renvoie un tableau vide. Voici la façon dont j'appelle depuis create-ticket.component.ts

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

J'ai essayé de récupérer d'abord la réponse de l'API et de la stocker dans une variable, puis d'appeler cette fonction this.service.getQuestions(24) ; mais l'erreur suivante s'est produite

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)

et les données de Formgorup restent vides. Veuillez m'aider à résoudre ce problème. Merci d'avance

2voto

Striker Points 609

Finalement, après un long travail de recherche et développement, j'ai réussi à faire ce travail.

  1. dans le service respond avant la réponse de l'API
  2. le formulaire est créé avant que les données n'arrivent dans l'entreprise

Pour la première question, j'ai donc utilisé le concept de async await Fonctionnalité dans angular

Dans le fichier create-ticket.component.ts nous avons ajouté async et await comme ceci.

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

et dans le service nous retournons une promesse

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

il répond comme une promesse donc il attend la réponse de l'api. this.apiservice.getAllInputFields(id) est juste un appel http api du serveur.

Pour le deuxième problème, j'ai utilisé une petite solution. J'ai ajouté *ngIf dans le formulaire pour que lorsque l'api répond avec des données, seul le formulaire commence à être construit.

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

C'est tout et le problème est résolu.

1voto

jcuypers Points 1673

Informations périmées basées sur stackblitz

Y soit exécuté

ngOnInit() {
  this.questions = this.service.getQuestions(24).subscribe(result => {
                do something with result }, 
      err => { something went wrong });
}

Voici un stackblitz, basé sur le vôtre : https://stackblitz.com/edit/angular-h8zakj?embed=1&file=src/app/question.service.ts

comme je l'ai dit, il y avait un problème avec votre setTimeout. les données n'étaient pas accessibles là où vous le souhaitiez.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X