11

I am having a slight problem, perhaps someone can help as I have been working on this for over an hour...

In my component file I create a form using a method, then I use another method to make an API call, return some data and set one of the controls of the created array. Here is some of my simplified code, just the ngOnInit, constructor and relevant methods

constructor(public dialogRef: MatDialogRef<EditAccountComponent>,
          @Inject(MAT_DIALOG_DATA) private data,
          private apiService: ApiService,
          private emailUniqueValidator: EmailUniqueValidator) {
            this.user = data;
}

ngOnInit(): void {
    this.editAccountForm = this.createEditUserForm();
    this.getRoles();
}

createEditUserForm(): FormGroup {
    return new FormGroup({
        name: new FormControl(this.user.name, [Validators.required, Validators.max(50)]),
        email: new FormControl(
        this.user.emailAddress,
        [Validators.required, Validators.pattern('^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$')],
        this.emailUniqueValidator.validate.bind(this)
        ),
        companies: new FormControl(this.user.tags.company),
        roles: new FormArray([])
    });
}

getRoles(): any {
        this.apiService.getUserRoles(this.data.id).subscribe(roles => {
        // roles = ['role 1', 'role 2', 'role 3'];
        this.editAccountForm.controls['roles'].setValue(roles);
    });
}

In my createEditUserForm method I create the roles property using new FormArray([]) as the value can be a string array that has a maximum of 4 values, for example: ['role 1', 'role 2','role 3','role 4']. In my getRoles method I return a string array and try to set it to the form's roles property. However this gives me an error;

"There are no form controls registered with this array yet. If you're using ngModel, you may want to check next tick (e.g. use setTimeout)."

So I tried to change .setValue(roles) to .patchValue(roles)... but this didn't work, I also tried to create an array of FormControls with each value from the this.apiService.getUserRoles call and this doesn't work... can someone please tell me how to set the value of the roles form property with the string array returned from the API?

2

2 Answers 2

13

Your FormArray is not properly initialized and does not contain any FormControl within which following roles should be set. You will need to populate it with initial value as written in Angular documentation If you would like to set them dynamically depend of the quantity of the roles see code under link https://stackblitz.com/edit/angular-6dzav1

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

2 Comments

Thank heavens for people as clever as you!
This answer suggests that you need a new FormArray instance every time the size of the array value changes. And indeed this appears to be the case. If you intially set an empty array const fArray = fb.array([]) then you can't update with a non-empty one fArray.setValue([1,2]) and it complains with the above error. I'm concerned about a memory leak if we are to re-initialize FormArray every time. Does setControl() properly clean the old instance even if it's part of a complex/nested FormGroup?
0

You need to check if the component is rendered and appearing on HTML. I had this problem and saw that it was inside a ngIf while was being checked on valuechanges.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.