0

I have a Form which uses a formArray :

  initForm() {
    this.mainForm = this.formBuilder.group({
      foos: this.formBuilder.array([], [Validators.required]),
    });
    
  getFoos(): FormArray {
    return this.mainForm.get('foos') as FormArray;
  }

  onAddFoo() {
    this.getFoos().push(this.formBuilder.control(''));
  }

the Foo item is a subForm :

export interface FooFormValues {
    id: number,
    toto: number,
}

@Component({
  selector: 'ngx-Foo',
  templateUrl: './Foo.component.html',
  styleUrls: ['./Foo.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => FooComponent),
      multi: true
    },
    {
      provide: NG_VALIDATORS,
      useExisting: forwardRef(() => FooComponent),
      multi: true
    }
  ]
})
export class FooComponent implements OnInit, OnDestroy, ControlValueAccessor {

  @Input() inErrors: any[];

  destroy$: Subject<boolean> = new Subject<boolean>();
    
  FooForm: FormGroup;

  constructor(
    private formBuilder: FormBuilder,
    public translate: TranslateService,
    ) { 
    }

  get f() { return this.FooForm.controls; }

/////////////////////////////////////////////////////////
////// OnInit & onDestroy
/////////////////////////////////////////////////////////
  ngOnInit(): void {
        this.initForm();
        this.FooForm.valueChanges.takeUntil(this.destroy$).subscribe(value => {
            this.onChange(value);
            this.onTouched();
        });
        
  }

  ngOnDestroy() {
    this.destroy$.next(true);
    this.destroy$.unsubscribe();
  }

//////////////////////////////////////////////////////////////////////////////
///// Control Value Accessor
//////////////////////////////////////////////////////////////////////////////

  get value(): FooFormValues {
    return this.FooForm.value;
  }

  set value(value: FooFormValues) {
    //if( value !== undefined && this.value !== value){ 
    if( value !== undefined ){      
        this.FooForm.patchValue(value);
        this.onChange(value);
        this.onTouched();
    }
  }

  onChange: any = () => {}

  onTouched: any = () => {
  }

  // this method sets the value programmatically
  writeValue(value) {
    if (value) {
        this.value = value;
    }

    if (value === null) {
      this.FooForm.reset();
    }

  }

// upon UI element value changes, this method gets triggered
  registerOnChange(fn) {
    this.onChange = fn;
  }

// upon touching the element, this method gets triggered
  registerOnTouched(fn) {
    this.onTouched = fn;
  }

  // communicate the inner form validation to the parent form
  validate(_: FormControl) {
    return this.FooForm.valid ? null : { profile: { valid: false } };
  }

  get errors() {
    return this.FooForm.errors ? null : this.FooForm.errors;
  }


//////////////////////////////////////////////////////////////////////////////
///// Miscellaneous Functions
//////////////////////////////////////////////////////////////////////////////

  initForm() {
    this.FooForm = this.formBuilder.group({
        id: '',
        toto: ['10', [Validators.required, Validators.min(0)]],
    });
  }

  onSubmitForm() {}

}

My main Form component uses a subscirption to valueChange :

this.mainForm.valueChanges.takeUntil(this.destroy$).subscribe(val => {...});

When add formArray item button is clicked, the main form onChange is triggered, but the val.foos is ["","",...]

I try to add :
    this.value={
        id: null,
        toto: 10,} 

in the InitForm fonction, but same result !

Thank you for your help

1 Answer 1

1

Trigger valueChanges manually by calling updateValueandValidity afterViewInit like this it will update parent formControl.

Try this:

ngAfterViewInit(){
    setTimeout(()=>{
      this.FooForm.updateValueAndValidity();
    })
  }

Working Example

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

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.