Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reactive form not receive default input value

I'm using angular and I have a reactive form for editing an item. When I open the component for editing, the inputs load value for object correctly, but if I don't click the input and change value, the value in reactive form is empty.

My code here:

 <form [formGroup]="entidadesForm">
        <div class="row">
            <div class="col-lg-12">
                <nb-card>
                    <nb-card-header>Digite os dados solicitados</nb-card-header>
                    <nb-card-body>
                        <div class="form-group">
                            <label class="container-title" >Nome</label>
                            <input type="text" autocomplete="off" formControlName="Nome"   value="{{nome}}" class="form-control" placeholder="Nome" class="form-control"
                            />
                        </div>
                        <div class="form-group" *ngIf="entidade === 'setor' || entidade === 'unidadeproduto' " >
                            <label class="container-title">Descricao</label>
                            <input type="text" autocomplete="off" value="{{descricao}}"placeholder="Descricao" class="form-control"  formControlName="Descricao"
                            />
                        </div>
                        <div class="form-group" *ngIf="entidade === 'unidadeproduto' " >
                                <label class="container-title">Pode Fracionar</label>
                                <select class="form-control"  formControlName="PodeFracionar" >
                                    <option *ngIf="!atualizar"></option>
                                    <option [selected]="podeFracionar == 'S'" value="S" >Sim</option>
                                    <option [selected]="podeFracionar == 'N'" value="N" >Nao</option>
                                </select>
                            </div>

                    </nb-card-body>
                </nb-card>
            </div>

        </div>
    </form>

and ts file

constructor(private fb: FormBuilder, private entidadesProdutoService: EntidadesProdutoService, private route : ActivatedRoute, private router: Router, private location: Location) {
    this.atualizar = false;
   }

  ngOnInit() {

    this.route.queryParams.subscribe( params =>{
       this.id = params['id'];
       this.nome = params['nome'];
       this.descricao = params['descricao'];
       this.podeFracionar = params['podeFracionar'];
       this.entidade = params['entidade'];
       if(this.id !== undefined) this.atualizar = true;
      });

    this.entidadesForm = new FormsModels(this.fb).formularioModel(this.entidade)

  }

  salvar( ){
    if(this.atualizar){
      this.entidadesProdutoService.atualizar(this.id, this.entidadesForm.value, this.entidade).subscribe(response => {
        this.location.back()
      },
    erro => console.log(erro))
    }else{
      this.entidadesProdutoService.salvar(this.entidadesForm.value, this.entidade).subscribe(response=>{
        this.location.back()
       },
     erro => {
       console.log(erro)
     })
    }
  }

the component to define a form here:

import { FormBuilder, FormGroup } from '@angular/forms';
export class FormsModels{

    constructor(public fb: FormBuilder){}

     public formularioModel(entidade): FormGroup{
        if(entidade === 'categoria' || entidade === 'marca' || entidade === 'subcategoria' || entidade === 'secao' ){
            return this.fb.group({
                Nome: this.fb.control('', [])
              })
            }

              else if(entidade === 'setor'){
            return this.fb.group({
                Nome: this.fb.control('', []),
                Descricao: this.fb.control('', [])
              })
            }
              else if(entidade === 'unidadeproduto'){
            return this.fb.group({
                Nome: this.fb.control('', []),
                Descricao: this.fb.control('', []),
                PodeFracionar: this.fb.control('', [])
              })
            }
        }

    }

when i load the component the inputs load correct value, see the image:

enter image description here

if i edit only input nome for exemple, the form value of inputs descricao and the select input pode fracionar will empty, see the console here.

enter image description here

like image 763
Davi Resio Avatar asked Mar 06 '26 20:03

Davi Resio


2 Answers

Your input fields are showing the correct value, because you set value="{{nome}}" in your html.

During your FormGroup creation you set an empty string as value in the control configuration this.fb.control('YOUR_EMTPY_STRING', []), so the value of the control is empty.

So you need to set the value of your controls during the FormGroup creation, e.g. like this:

this.route.queryParams.subscribe( params =>{
   this.id = params['id'];
   this.nome = params['nome'];
   this.descricao = params['descricao'];
   this.podeFracionar = params['podeFracionar'];
   this.entidade = params['entidade'];
   if(this.id !== undefined) this.atualizar = true;

   // After receiving the router params init your FormGroup
   this.entidadesForm = new FormsModels(this.fb).formularioModel(this.entidade)
});

...

public formularioModel(entidade): FormGroup{
    if(entidade === 'categoria' || entidade === 'marca' || entidade === 'subcategoria' || entidade === 'secao' ){
        return this.fb.group({
            Nome: this.fb.control(this.nome, [])
        })
    } else if(entidade === 'setor'){
        return this.fb.group({
            Nome: this.fb.control(this.nome, []),
            Descricao: this.fb.control(this.descricao, [])
        })
    } else if(entidade === 'unidadeproduto'){
        return this.fb.group({
            Nome: this.fb.control(this.nome, []),
            Descricao: this.fb.control(this.descricao, []),
            PodeFracionar: this.fb.control(this.podeFracionar, [])
        })
    }
}

Or otherwise you just update the value of your FormGroup like following:

this.route.queryParams.subscribe( params =>{
   this.id = params['id'];
   this.nome = params['nome'];
   this.descricao = params['descricao'];
   this.podeFracionar = params['podeFracionar'];
   this.entidade = params['entidade'];
   if(this.id !== undefined) this.atualizar = true;

   // Updates the value of your FromGroup
   this.entidadesForm.setValue({Nome: this.nome, Descricao: this.descricao, PodeFracionar: this.podeFracionar});
});
like image 181
Batajus Avatar answered Mar 08 '26 09:03

Batajus


You're missing a fundamental design principle about Angular.

In Angular, the single point of truth is the model. Not the DOM. The DOM is generated based on the model. So value="{{descricao}}" and [selected]="podeFracionar == 'S'" for example are wrong.

You must not set the selected/entered value in the DOM. You must set it in the model. And Angular will set the value/select the option based on what the model contains, because the input/select is bound to the model.

So, initialize the values of the FormControls, when creating the FormGroup. And the view will display/select these values. You're doing the reverse, which is incorrect.

like image 20
JB Nizet Avatar answered Mar 08 '26 09:03

JB Nizet