Angular2 formBuilder and Validators do not validate in all cases

1

It turns out that I have a component to register articles in angular2. When I create the empty component, the validations are carried out correctly. Now, when I use the same component to edit an article and initialize the form with data, it is not validated. What may be happening?.

I put the sources ... article-form.component.ts

import { Component, ViewEncapsulation, OnInit, ViewChild } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { DropdownModule, ModalDirective } from 'ng2-bootstrap';
import { ToasterContainerComponent, ToasterService } from 'angular2-toaster';

import { WSRESTArticle } from '../../../../services/article.services';
import { ArticleVO } from  '../../../../services/ArticleVO';


@Component({
selector: 'article',
providers: [ToasterService],
template: require('./article-form.html'),
encapsulation: ViewEncapsulation.None
})
export class ArticleFormComponent implements OnInit {
@ViewChild('childModal') childModal: ModalDirective;
private toasterService: ToasterService;

public trxForm;

title : string;
caption: string;
add: boolean;
idarticle: number;

states = [{"id": 1, "state": 'Habilitado'}, {"id": 0, "state": 'Inhabilitado'}];

constructor(public fb: FormBuilder, 
            private router: Router,
            private route: ActivatedRoute, 
            protected serviceArticle: WSRESTArticle,
            toasterService: ToasterService) {

    console.log('Article-Form constructor');
    this.toasterService = toasterService;

    this.trxForm =this.fb.group({
      description:  ["", [Validators.required]],
      price:        ["", [Validators.required, Validators.pattern('^[0-9]+(\.[0-9]{1,2})?$')]],
      flagenabled:  ["", [Validators.required]]
    });
}

ngOnInit() {
    var id = this.route.params.subscribe(params => {
      var id = params['id'];

      this.title = id ? 'Editar Artículo' : 'Agregar Nuevo Artículo';
      this.caption = id ? 'Confirmar cambios' : 'Confirmar alta';
      this.add = id ? false : true;

      if (!id)
          return;

      this.idarticle = id;

      this.serviceArticle.Get(this.idarticle)
          .subscribe((data:ArticleVO) => this.fillArticleForm(data),
          error => console.log(error),
          () => console.log('Get article complete'));
    });
}

doCleanPrepare(): void {
  this.trxForm.reset();
}

goBack(): void {
  this.router.navigate(['pages/articles']);
}

doPost(): void {
    if (!this.idarticle)
    {
      this.serviceArticle
        .Add(this.trxForm.value.description, this.trxForm.value.price, this.trxForm.value.flagenabled.id)
        .subscribe((data:string) => {
          console.log(data);
          this.toasterService.pop('success', 'Agregar Artículo', 'Artículo insertado correctamente!.');
        },
        error => {
          console.log(error);
          this.toasterService.pop('error', 'Agregar Artículo', 'Error - El Artículo no puedo ser agregado!.');
        },
        () => console.log('insertar article finalizado'));
    }
    else {
      let article = new ArticleVO();
      article.description = this.trxForm.value.description;
      article.price = this.trxForm.value.price;
      article.flagenabled = this.trxForm.value.flagenabled.id;

      this.serviceArticle
        .Update(this.idarticle, article)
        .subscribe((data:ArticleVO) => {
          console.log(data);
          this.toasterService.pop('success', 'Editar Artículo', 'Artículo actualizado correctamente!.');
        },
        error => {
          console.log(error);
          this.toasterService.pop('error', 'Editar Artículo', 'Error - El Artículo no puedo ser actualizado!.');
        },
        () => console.log('actualizar article finalizado'));
    }
}

private fillArticleForm(data:ArticleVO): void {

    this.trxForm = this.fb.group({
      description: data.description,
      price: data.price,
      flagenabled: this.states.find(myobj => myobj.id == data.flagenabled)
    });
}

}

article-form.html

<div class="widgets">
<toaster-container></toaster-container>
  <div class="row">
    <button class="btn btn-success col-lg-1" (click)="goBack()">Regresar</button>
    <h3 class="col-lg-11">{{title}}</h3>
  </div>
</div>
<br>

<div class="row">
  <form [formGroup]="trxForm">
    <div class="form-group" [ngClass]="{'has-error':!trxForm.controls['description'].valid && trxForm.controls['description'].touched}">
      <label for="description">Descripción</label>
      <input formControlName="description" type="text" class="form-control" id="description" placeholder="Descripción">
      <div *ngIf="!trxForm.controls['description'].valid && trxForm.controls['description'].touched">
        <p *ngIf="trxForm.controls['description'].hasError('required')" class="alert alert-danger">* El campo Descripción es obligatorio</p>
      </div>
    </div>

<div class="form-group" [ngClass]="{'has-error':!trxForm.controls['price'].valid && trxForm.controls['price'].touched}">
  <label for="price">Precio</label>
  <input formControlName="price" type="text" class="form-control" id="price" placeholder="Precio">
  <div *ngIf="!trxForm.controls['price'].valid && trxForm.controls['price'].touched">
    <p *ngIf="trxForm.controls['price'].hasError('required')" class="alert alert-danger">* El campo Precio es obligatorio</p>
    <p *ngIf="trxForm.controls['price'].hasError('pattern')" class="alert alert-danger">* El campo Precio debe ser numérico</p>
  </div>
</div>

<div class="form-group" [ngClass]="{'has-error':!trxForm.controls['flagenabled'].valid && trxForm.controls['flagenabled'].touched}">
  <label for="flagenabled">Habilitado</label>
  <select formControlName="flagenabled" name="flagenabled" class="form-control">
    <option [ngValue]="i" *ngFor="let i of states" >{{i.state}}</option>
  </select>
  <div *ngIf="!trxForm.controls['flagenabled'].valid && trxForm.controls['flagenabled'].touched">
    <p *ngIf="trxForm.controls['flagenabled'].hasError('required')" class="alert alert-danger">* El campo Habilitado es obligatorio</p>
  </div>
</div>

<button class="btn btn-danger" [disabled]="!trxForm.valid" (click)="doPost()">{{caption}}</button>
<button class="btn btn-success" [hidden]="!add" (click)="doCleanPrepare()">Limpiar y Preparar Nuevo</button>

  </form>
</div>
<br>
    
asked by Emiliano Torres 11.01.2017 в 18:34
source

2 answers

0

After a while I managed to solve this problem. It was in the FillArticleForm method. I had not put the validators (assuming that when I declared it was enough) ... that is why the create worked, but in the edit, as I put them, I did not. I leave the method in case someone serves. Thanks!.

private fillArticleForm(data:ArticleVO): void {

        this.trxForm = this.fb.group({
          description:  [data.description, [Validators.required]],
          price:        [data.price, [Validators.required, Validators.pattern('^[0-9]+(\.[0-9]{1,2})?$')]],
          flagenabled:  [this.states.find(myobj => myobj.id == data.flagenabled), [Validators.required]]
        });
    }
    
answered by 08.04.2017 / 20:09
source
1

It has to do with how you are handling the feedback or handling of the errors, to do the same thing that you are trying to do, I do:

<div class="form-group row">
  <div class="col-md-6">
    <!-- Name Field -->
    <label for="example-name" class="form-control-label">Nombre:</label>
    <div class="input-group">
      <input type="text" id="example-name" placeholder="Example" class="form-control" minlength="3" maxlength="24" name="name" [(ngModel)]="example.name" #name="ngModel" required>
    </div>
    <!-- Feedback name -->
    <div *ngIf="name.errors && name.touched" class="alert alert-danger">
      <div [hidden]="!name.errors.required">
        El nombre es obligatorio.
      </div>
      <div [hidden]="!name.errors.minlength">
        El nombre debe ser mayor o igual a 3 caracteres.
      </div>
      <div [hidden]="!name.errors.maxlength">
        El nombre debe ser menor a 25 caracteres.
      </div>
    </div>
  </div>
    
answered by 08.04.2017 в 05:31