简体   繁体   中英

Reative form - Group with an Array and with another group

I am trying to build an angular project with reative forms: This is the json file:

{
"idReceita": 115,
"nomeReceita": "aa",
"dificuldade": "Fácil",
"quantidadeDoses": 10,
"tempoPreparacao": 15,
"statusReceita": "Aprovada",
"visualizacoes": 1,
"instrucoes": "asasasa",
"categoria": "Snacks",
"idUtilizador": 1,
"utilizador": null,
"relReceitaIngredientes": [
    {
        "idRelReceitaIngrediente": 11,
        "idReceita": 115,
        "idIngrediente": 107,
        "quantidade": 250,
        "umedida": "gr",
        "ingrediente": {
            "idIngrediente": 107,
            "nomeIngrediente": "Arroz"
        }
    }
]

}

this is my class:export interface Receita {
  idReceita: number;
  nomeReceita: string;
  dificuldade: string;
  quantidadeDoses: number;
  tempoPreparacao: number;
  statusReceita: string;
  visualizacoes: number;
  instrucoes: string;
  categoria: string;
  idUtilizador: number;
  utilizador: null;
  relReceitaIngredientes: RelReceitaIngrediente[];
}

export interface RelReceitaIngrediente {
  idRelReceitaIngrediente: number;
  idReceita: number;
  idIngrediente: number;
  quantidade: number;
  umedida: string;
  ingrediente: Ingrediente;
}

export interface Ingrediente {
  idIngrediente: number;
  nomeIngrediente: string;
}

My project is about a recipe site. An user can create a recipe, this recipe include a recipe ingredient relation. In MySQL I have the ingredient table, then I have the recipe table in the middle I have one to bind this two (relReceitaIngredientes)

I already try everything and anything works.

this is my code:


  loading = false;
  ingredientes: Ingrediente[] = [];
  form!: FormGroup;
  submitted = false;
  control!: FormControl;
  currentUser: Utilizador;
  id: number;

  get f() {
    return this.form.controls;
  }
  get relReceitaIngredientes() {
    return this.form.controls['relReceitaIngredientes'] as FormArray;
  }
  get ingrediente() {
    return this.form.controls['ingrediente'] as FormGroup;
  }
  constructor(
    private readonly fb: FormBuilder,
    private rs: ReceitaService,
    private alertService: AlertService,
    private router: Router,
    private authenticationService: AuthserviceService
  ) {
    this.currentUser = this.authenticationService.currentUserValue;
  }

  ngOnInit() {
    this.form = this.fb.group({
      idReceita: [0, Validators.required],
      nomeReceita: ['', Validators.required],
      dificuldade: ['', Validators.required],
      quantidadeDoses: ['', Validators.required],
      tempoPreparacao: ['', Validators.required],
      statusReceita: ['Inativo', Validators.required],
      instrucoes: ['', Validators.required],
      categoria: ['', Validators.required],
      idUtilizador: [this.currentUser.idUtilizador, Validators.required],
      relReceitaIngredientes: this.fb.array([
        this.fb.group({
          idRelReceitaIngrediente: [0, Validators.required],
          idIngrediente: [0, Validators.required],
          quantidade: ['', Validators.required],
          umedida: ['', Validators.required],
          ingrediente: this.fb.group({
            idIngrediente: [0, Validators.required],
            nomeIngrediente: ['', Validators.required],
          }),
        }),
      ]),
    });

    this.rs
      .getAllIngredientes()
      .pipe(first())
      .subscribe((ingredientes) => {
        this.loading = false;
        this.ingredientes = ingredientes;
      });
  }

  onSubmit() {
    this.submitted = true;
    this.alertService.clear();
    if (this.form.invalid) {
      return;
    }

    this.loading = true;
    this.criarReceita();
    // reset alerts on submit
  }
  private criarReceita() {
    this.rs
      .criarReceita(this.form.value)
      .pipe(first())
      .subscribe({
        next: () => {
          this.alertService.success('Receita criada com sucesso', {
            keepAfterRouteChange: true,
          });
          this.router.navigate(['/asminhasreceitas']);
        },
        error: (error) => {
          this.alertService.error(error);
          this.loading = false;
        },
      });
  }
  addrelReceitaIngredientes() {
    this.relReceitaIngredientes.push(this.fb.control(''));
  }

In the internet exist a lot of examples with a group with an array. But I don't find any with Group->array->Group **

Here it is, hope it helps.

https://stackblitz.com/edit/angular-ivy-wqwo2g?file=src/app/app.module.ts

Html part

  <form [formGroup]="receitaForm">
    <input formControlName="nomeReceita">
  </form>
  <div>
    <div>Demo Data<pre>{{ myReceita | json}}</pre></div>
    <div>Form Data<pre>{{receitaForm.value | json}}</pre></div>
  </div>

ts Part

    import {Component, forwardRef, OnInit} from '@angular/core';
    import {FormArray, FormBuilder, FormGroup, Validators} from '@angular/forms';
    import {Receita} from './models';
    
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html'
    })
    export class AppComponent implements OnInit {
      // Or Demo data
      myReceita: Receita = {
        idReceita: 115,
        nomeReceita: 'aa',
        dificuldade: 'Fácil',
        quantidadeDoses: 10,
        tempoPreparacao: 15,
        statusReceita: 'Aprovada',
        visualizacoes: 1,
        instrucoes: 'asasasa',
        categoria: 'Snacks',
        idUtilizador: 1,
        utilizador: null,
        relReceitaIngredientes: [{
          idRelReceitaIngrediente: 11,
          idReceita: 115,
          idIngrediente: 107,
          quantidade: 250,
          umedida: 'gr',
          ingrediente: {
            idIngrediente: 107,
            nomeIngrediente: '107Arroz',
          },
        }, {
          idRelReceitaIngrediente: 12,
          idReceita: 115,
          idIngrediente: 107,
          quantidade: 250,
          umedida: 'gr',
          ingrediente: {
            idIngrediente: 108,
            nomeIngrediente: '108Arroz',
          },
        }],
      };
    
    
      // Our Forms Each one is represents a model nested or not
      receitaForm!: FormGroup;
    
      constructor(private readonly fb: FormBuilder) {
      }
    
      get relReceitaIngredientes(): FormArray {
        return this.receitaForm.get('relReceitaIngredientes') as FormArray;
      }
    
      ngOnInit(): void {
        this.receitaForm = this.fb.group({
          idReceita: [0, Validators.required],
          nomeReceita: ['', Validators.required],
          dificuldade: ['', Validators.required],
          quantidadeDoses: ['', Validators.required],
          tempoPreparacao: ['', Validators.required],
          statusReceita: ['Inativo', Validators.required],
          instrucoes: ['', Validators.required],
          categoria: ['', Validators.required],
          idUtilizador: ['currentuserid', Validators.required],
          relReceitaIngredientes: new FormArray([]),
        });
    
        this.receitaForm.patchValue(this.myReceita);
        for(let ing of this.myReceita.relReceitaIngredientes){
          var f = this.newReceitaIngredientForm();
          f.patchValue(ing)
          this.relReceitaIngredientes.push(f)
        }
      }
    
      newReceitaIngredientForm(): FormGroup {
        return this.fb.group({
          idRelReceitaIngrediente: [0, Validators.required],
          idIngrediente: [0, Validators.required],
          quantidade: ['', Validators.required],
          umedida: ['', Validators.required],
          ingrediente: this.fb.group({
            idIngrediente: [0, Validators.required],
            nomeIngrediente: ['', Validators.required],
          }),
        });
      }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM