Search code examples
angulartypescript

angular typed form events to outputFromObservable breaks when form get assigned to new form object


Sorry for the wordy title.

I have an angular v18 typed form in a component that exposes as an output the ValueChangeEvent form event through the outputFromObservable() function:

export class SessionEditFormComponent {
  private fs = inject(SessionFormService);
  sessionForm: FormGroup<SessionForm> = this.fs.getDefaultForm();
  session = input.required<ProgramSession>();
  onFormValueChange = outputFromObservable(
    this.sessionForm.events.pipe(
      filter((e) => e instanceof ValueChangeEvent),
      debounceTime(1000),
      distinctUntilChanged()
    )
  );

  constructor() {
    effect(() => {
      if (this.session().title !== undefined) {
        console.log('session effect', this.session());
        this.fs.patchForm(this.session());
      }
    });
  }
}

the custom function "fs.patchForm()" takes a custom object called session and builds a new formgroup with mutiple nested form arrays. It then returns a NEW form that gets assigned to the components sessionForm property. The parent component catches the onFormValueChange events (onFormValueChange)="onFormChange($event)"

THE PROBLEM:

once the form gets reassigned in the signal/constructor effect it breaks the onFormValueChange observable. It no longer emits changes. If I remove the effect all the form events get emitted as expected.

Can someone help me keep the change events emitting after assigning a new form to the sessionForm property.

thanks


Solution

  • If you want to reassign the form, you'd have to use form as a subject or signal, whichever you like the most.

    sessionForm$: Subject<FormGroup<SessionForm>> = new BehaviorSubject(this.fs.getDefaultForm());
      onFormValueChange = outputFromObservable(
        this.sessionForm.pipe(
          switchMap(form => form.events),
          filter((e) => e instanceof ValueChangeEvent),
          debounceTime(1000),
          distinctUntilChanged()
        )
      );
    setNewForm() {
      const newForm = ...;
      this.sessionForm$.next(newForm);
    }