Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

There is no FormControl instance attached to form control element with name

I have created a form in Angular 2 with which users can edit a SearchProfile which they can select from a list. Initially everything works fine but when i select a different item from the list of SearchProfiles I receive the following exception: There is no FormControl instance attached to form control element with name: controlName. The whole thing consists of 3 elements: 2 components SelectProfileComponent, SearchProfileComponent and a service ProfileService. ProfileService contains the ActiveProfile which is the selected SearchProfile for editing. ProfileService looks like this:

@Injectable()
export class ProfileService {
    private activeProfileSource = new ReplaySubject<ISearchProfile>();
    activeProfile$ = this.activeProfileSource.asObservable();

    constructor(private http: Http) {
        this.selectProfile();
    }

    public getSearchProfile(profileId: number = null): Observable<ISearchProfile> {
        let url = `<url>?profileid=${profileId}`;
        this.http.get(url).map((result) => {
            return <ISearchProfile>.result.json();
        });
    }

    public selectProfile(profileId: number = null) {
        this.getSearchProfile(profileId).subscribe((p) => {
            this.activeProfileSource.next(p);
        });
    }
}

SelectProfileComponent contains a list with profile which triggers a change-event when a SearchProfile is selected.

<select (change)="setActiveProfile($event.target.value)">
    <option *ngFor="let profile of profiles" [value]="profile.Id" [innerHtml]="profile.name"></option>
</select>

export class ProfileSelectionComponent implements OnInit {
    private profiles: ISearchProfile[] = null;

    constructor(private profileService: ProfileService) {}

    //get profiles logic

    public setActiveProfile(profileId: number): void {
        this.profileService.selectProfile(profileId);
    }
}

The SearchProfileComponent has a Subscription to the activeProfile and should show the properties of the activeProfile so the user can edit them. SearchProfileComponent looks like this:

<form [formGroup]="profileForm" *ngIf="!isLoading">
    <input type="text" name="name" formControlName="name" [(ngModel)]="searchProfile.name" />
</form>

export class SearchProfileComponent implements OnInit {
    private isLoading: boolean = true;
    private activeProfileSubscription: Subscription;
    private searchProfile: ISearchProfile = null;
    public profileForm: FormGroup;

    constructor(private profilService: ProfileService
        private formBuilder: FormBuilder) { }

    ngOnInit() {
        this.activeProfileSubscription = this.profileService.activeProfile$.subscribe((profile: ISearchProfile) => {
            this.searchProfile = profile;
            this.createForm();
            this.isLoading = false;
        });
    }
    private createForm() {
        this.profileForm = this.formBuilder.group({
            ["name"]: [this.searchProfile.name, null]
        });
    }
}
like image 790
Bunnynut Avatar asked Mar 15 '18 10:03

Bunnynut


People also ask

What is FormControl name?

The name corresponds to a key in the parent FormGroup or FormArray . Accepts a name as a string or a number. The name in the form of a string is useful for individual forms, while the numerical form allows for form controls to be bound to indices when iterating over controls in a FormArray . @Input('disabled')

Can we use FormControl without FormGroup?

Sometimes, we don't need a FormGroup, as our form might only consist of a single form control. Think of a search field that let's you search for products in an e-commerce application. Technically, we don't even need a <form> element for that.


2 Answers

I solved this in this way:

Before:

formControlName="description"

After:

[formControl]="form.controls['description']"
like image 192
Kuzenko Lubko Avatar answered Sep 19 '22 05:09

Kuzenko Lubko


The creation of your FormGroup is a little bit wrong. You dont need to wrap the control name in brackets and double quotes. Read more about reactive forms on official angular docs.

Change your creation of FormGroup from this:

this.profileForm = this.formBuilder.group({
            ["name"]: [this.searchProfile.name, null]
});

to this:

this.profileForm = this.formBuilder.group({
            name: [this.searchProfile.name]
});

And you should make some changes in your html. Hint: If you are using reactive forms, you don't need [(ngModel)] on inputs, remove that. Here is right html for you input:

<form [formGroup]="profileForm" *ngIf="!isLoading">
    <input type="text" name="name" formControlName="name" />
</form>
like image 23
Gregor Doroschenko Avatar answered Sep 22 '22 05:09

Gregor Doroschenko