How to edit reactive form from an observable data in angular imperatively without subscribing to the Observable?

375 Views Asked by At

Below is the process I've been using to subscribe and then update a reactive form based on observable data.

Maybe there's a way to fix the problem without subscribing to the observable and changing the value.

@Component({
  selector: 'app-my-component',
  template: `
    <form [formGroup]="myForm">
      <input formControlName="name" />
      <input formControlName="email" />
    </form>
  `,
})
export class MyComponent implements OnInit {
  myForm: FormGroup;

  constructor(private fb: FormBuilder, private ds: DataService) {}

  ngOnInit() {
    this.myForm = this.fb.group({
      name: '',
      email: '',
    });

    ds.data$.subscribe((data) => {
      this.myForm.setValue({
        name: data.name,
        email: data.email,
      });
    });
  }


}
2

There are 2 best solutions below

0
Andrei On

generally a way to eliminate of subscriptions is to use async pipe in wrapper

@Component({
  template: `<app-user-form-component *ngIf="user$ | async as user"  [user]="user"/>`,
  // closed tag is a new feature of angular
  selector: 'app-update-user-form-container'
}) 
class UpdateUserFormContainer {
  user$ = inject(DataService).data$;
}

and the form itself can handle user update inside of NgOnInit or ngOnChanges(if there may be several updates and it is important to set value for the form in this case)

export class MyComponent implements OnInit {
  myForm = inject(NonNullableFormBuilder).group({
     name: '',
     email: '',
  }); // this way form is not just FormGroup but the type is inferred from fields
  // i.e. this.myForm.getRawValue() would return you {name: string, email: string};
  @Input({required: true}) user1: User; // required input is new feature of angular
  
  ngOnChanges(changes: SimpleChanges) {
    if('user' in changes) {
      this.myForm.setValue({
       name: this.user.name,
       email: this.user.email,
     })
    }
  }
}

note: some very bleeding edge features of angular are used in this example. it is possible to follow the same pattern but without every feature used

1
shakalone On

Your code doesn't have any problem. Since you have to populate a form with backend data, you MUST subscribe to fetch your data.

HTTP Requests using Angular HttpClient results in an RXJS Observable, so the correct way to retrieve its holding data is performing a subscription.