1

I'm trying to set a validator inside a formArray in angular and I don't know how to create it, my formGroup is

 itemsForm = this.fb.group({
    array: this.fb.array([this.fb.control(['']).setValidators(Validators.required)]),
  });

I tryed setting the validator inside the array but in the html it let me add another field without validated if this is empty or not my code is this:

HTML

<section [formGroup]="itemsForm" class="m-5">
  <section
    formArrayName="array"
    class="justify-content-center d-flex flex-wrap"
  >
    <div>
      <section class="d-flex flex-wrap">
        <div class="">
          <h4>Items Selected</h4>
        </div>
        <div class="">
          <button class="btn btn-primary" (click)="addItem()">Add Item</button>
        </div>
      </section>

      <section class="d-flex flex-column">
        <div
          class="form-group d-flex flex-row align-items-center"
          *ngFor="let item of itemsArray.controls; let index = index"
        >
          <h2 class="mr-2">item</h2>
          <input
            type="text"
            [formControlName]="index"
            class="form-control"
            [ngClass]="{
              'is-invalid': item.touched  && !item.valid
            }"
          />
        </div>
      </section>
    </div>
  </section>
</section>

TS

  @Input() defaultOption: string = '';
  @Input() optionsList: Array<string> = [];
  @Output() optionSelected = new EventEmitter<string>();

  selected: string = '';
  constructor(private fb: FormBuilder) {}
  itemsForm = this.fb.group({
    array: this.fb.array([this.fb.control(['']).setValidators(Validators.required)]),
  });


  get itemsArray(){
    return this.itemsForm.get('array') as FormArray
  }

  ngOnInit(): void {}

  updateSelection() {
    this.optionSelected.emit(this.selected);
  }
  addItem() {
    this.itemsArray.push(this.fb.control(''));
  }
2
  • 1
    When adding a new formControl is also need add a validator this.itemsArray.push(this.fb.control('', [Validators.required])) . Another way is to add a validator for all FormArray for example stackoverflow.com/questions/57794118/… Commented Oct 4, 2021 at 19:16
  • Thanks for this example but it is got me errors of invalid type Commented Oct 5, 2021 at 13:15

1 Answer 1

1

try this...

  constructor(private fb: FormBuilder) {}
  itemsForm = this.fb.group({
    array: this.fb.array([this._createFormArrayControls()]),
  });


  get itemsArray(){
    return this.itemsForm.get('array') as FormArray
  }

  ngOnInit(): void {}

  private _createFormArrayControls(): FormControl{
   return this.fb.control('', Validators.required)
  }

in the future, if you would need to initialize the form array to some default value based on an array you could then convert FormControl to FormGroup and do this:

@Input() set items(value: Item[]) {
    itemsForm = this.fb.group({
    array: this.fb.array(value.map(i => this._createFormArrayGroup(i))),
  });
};
  constructor(private fb: FormBuilder) {}   
    
  ngOnInit(): void {}

  private _createFormArrayGroup(item?: Item): FormGroup{   
   return this.fb.group({
    myItem: this.fb.control(item.Value, Validators.required)
   })
  }
Sign up to request clarification or add additional context in comments.

3 Comments

I'm doing the map to add default values but my itemForm is not adding it, have you any idea?
if the map is not workings its because items is not populated with values. Constructor gets executed very early, before @Input() gets populated. If you move that form initialization code into ngAfterViewInit() lifecycle hook or inside the @Input setter, the data should be there and everything should work as expected. Let me update my answer.
that is more logic, I found a way to do it, but if you update your answer it will be better

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.