0

I'm using Angular 8 and Reactive Form.

I want to add FormArray control to the main form group.

The component is

export class RsvpComponent implements OnInit {

  form: FormGroup;

  constructor(
    private fb: FormBuilder
  ) { }

  ngOnInit() {
    this.form = this.fb.group({
      name: ['', [
        Validators.required
      ]]
    });
  }

  public addGuest() {
    if (!this.form.get('guests')) {
      this.addGuestControl();
    }

    this.getGuestControlArray().push(this.guestControl());
  }

  private addGuestControl() {
    this.form.addControl('guests', new FormArray([]));
  }

  private getGuestControlArray() {
    return this.form.get('guests') as FormArray;
  }

  private guestControl(): FormGroup {
    const guestGroup = this.fb.group({
      name: ['', [
        Validators.required
      ]]
    });

    return guestGroup;
  }

  onSubmit() {
    console.log('submitted: ', this.form.value);
  }
}

The addGuest is called on click of a button. By default there will be no guests hence, no guests control in the form.

On calling the method addGuest, it first checks if guests control is there, if not then adds the control first which is a FormArray type.

This works fine on first click and controls are added, but on clicking of the submit button, onSubmit is called and the added guest data is not in the value.

When calling again addGuest the check for guests control fails.

Stackbliz: https://stackblitz.com/edit/angular-bipdyu

The weird condition: The code is working in the Stackblitz, but when I copy the same code in my component, (removing everything), it's not working.

9
  • If possible then provide stackblitz Commented Jan 9, 2020 at 7:57
  • I have added the stackblitz url in the question. But it seems weird, that same thing is working in Stackblitz but not in my app. Commented Jan 9, 2020 at 8:11
  • Check for console error Commented Jan 9, 2020 at 8:11
  • In your template, formControlName='guests'(or [formControl]="...") is bound to a component or to a DOM element? Commented Jan 9, 2020 at 8:14
  • @Andrei The controls are not registered yet. Commented Jan 9, 2020 at 8:16

2 Answers 2

0

As far as I can see you would need to change your guestControl() method to return a FormControl instead of a FormGroup. A FormGroup cannot track a internal value it only acts as a superiour structure to 'group' (!) your FormControls. For any actual value you would need those.

private guestControl(): FormControl {
  const guestControl = this.fb.control('', Validators.required);
  return guestControl;
}

Should do the trick.

Sign up to request clarification or add additional context in comments.

4 Comments

I don't think that's a valid syntax. The first argument of FormControl should be formState, which can be either a primitive value(ex: ''/null) or a boxed value({ value: '', disabled: false }). Source
If it's the case, then remove the return type should work. But it's not working.
You are totally right. the above should fix the syntax
A FormGroup cannot track a internal value it well whole form is a FormGroup and yet it does track values and states.
0

The issue was related to Change Detection Strategy in Angular.

Same has been answered here: Angular @Input binding using function calling multiple times

Comments

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.