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 SearchProfile
s 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]
});
}
}
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')
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.
I solved this in this way:
Before:
formControlName="description"
After:
[formControl]="form.controls['description']"
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With