Home > front end >  Angular. Form control values from subscription
Angular. Form control values from subscription

Time:03-22

I have a form which has to look like this: enter image description here Values of userGroups are taken from Web Api and here I faced a problem. I implement function that uses subscription and gets User Groups from http. Form is created in the constructor. In this case (obviously) the value of userGroups is undefined because it was assigned in subscription.

export class UserAddComponent implements OnInit {
userForm: FormGroup;
userGroups: UserGroup[];

constructor(
    private http: HttpService,
    private fb: FormBuilder) {
        this.userForm = fb.group({
            'login': ['', [Validators.required]],
            'userGroups': this.fb.array(this.userGroups.map(x => !1)) // userGroups is undefined
        });
    }

    private getUserGroups() {
        this.http.get<ODataResponse>(`${this.soddApiUrl}/UserGroups`)
            .subscribe({
                next: (data: ODataResponse) => {
                    this.userGroups = <UserGroup[]>data.value;
                },
                error: () => { },
                complete: () => { }
            });
    }

    get login() { return this.userForm.get('login'); }
}

I tried another approach - to create form in subscription:

export class UserAddComponent implements OnInit {
userForm: FormGroup;
userGroups: UserGroup[];

constructor(
    private http: HttpService,
    private fb: FormBuilder) {
        this.http.get<ODataResponse>(`${this.soddApiUrl}/UserGroups`)
            .subscribe({
                next: (data: ODataResponse) => {
                    this.userGroups = <UserGroup[]>data.value;

                    this.userForm = fb.group({
                        'login': ['', [Validators.required],
                        'userGroups': this.fb.array(this.userGroups.map(x => !1))
                    });
                },
                error: (err) => { },
                complete: () => { }
            });
    }
  
    get login() { return this.userForm.get('login'); } // userFrom is undefined
}

In this case form is created fine but I get login is undefined error in template (because userForm value was assigned in subscription).

<form [formGroup]="userForm" (ngSubmit)="addUser()">
<div>
    <label for="login" >Login</label>
    <input type="text" nbInput fullWidth id="login" formControlName="login"
          <!-- login is undefined here -->
          [status]="login.dirty ? (login.invalid  ? 'danger' : 'success') : 'basic'"
          [attr.aria-invalid]="login.invalid && login.touched ? true : null" />
</div>

<div>
    <label >User Groups</label>
    <div *ngFor="let userGroup of userGroups; let i = index" formArrayName="userGroups">
        <nb-checkbox [formControlName]="i">{{userGroup.Title}}</nb-checkbox>
    </div>
</div>

So, in the first case I can't get access to array which values assigned in subscription, in the second case I can't get the value of form control because is is out of subscription.

Is there any solution to get it worked?

Thank you!

CodePudding user response:

move the form creation to OnInit method

ngOnInit() {
  this.createForm();
}

private createForm() {
    this.userForm = fb.group({
        'login': ['', [Validators.required]],
        'userGroups': this.fb.array((this.userGroups || []).map(x => !1)) // add empty array to avoid undefined error
    });
}

then in subscribed method call again the create form

yourHttpMethod() {
   this.http.get<ODataResponse>(`${this.soddApiUrl}/UserGroups`)
        .subscribe({
            next: (data: ODataResponse) => {
                this.userGroups = <UserGroup[]>data.value;

                this.createForm();
            },
            error: (err) => { },
            complete: () => { }
        });
}

if you can't lose the initial subscription then use the patchform in subscribe.

  • Related