Reputation: 457
I am looking for some help on trying to clear up, this all to common error. I am using forms in two different parts of my application, and the form works perfectly in one part, but not the other. I have imported both ReactiveFormsModule
and FormsModule
.
resolution.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ResolutionRoutingModule } from './resolution-routing.module';
import { ResolutionComponent } from './resolution/resolution.component';
import { ResolutionDetailComponent } from './resolution-detail/resolution-detail.component';
import { ResolutionListComponent } from './resolution-list/resolution-list.component';
import { NewResolutionComponent } from '../../forms/new-resolution/new-resolution.component';
import { MatFormFieldModule } from '@angular/material/form-field';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatDialogModule } from '@angular/material/dialog';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { MatCardModule } from '@angular/material/card';
import { ResolutionEditComponent } from '../../forms/resolution-edit/resolution-edit.component';
@NgModule({
declarations: [ResolutionComponent,
ResolutionDetailComponent,
ResolutionListComponent,
NewResolutionComponent,
ResolutionEditComponent],
imports: [
CommonModule,
ResolutionRoutingModule,
MatFormFieldModule,
ReactiveFormsModule,
MatDialogModule,
FormsModule,
MatInputModule,
MatSelectModule,
MatCardModule
]
})
export class ResolutionModule { }
In the component NewResolutionComponent
my form works as expected, and I get no errors.
new-resolution-component.html
(snippet: I only included one input function)
<form (ngSubmit)='onSubmit()'[formGroup]='ResolutionFormGroup'>
<mat-form-field>
<mat-label>Title</mat-label>
<input [formControl]='TitleControl' matInput placeholder="Title" required/>
</mat-form-field>
....
</form>
new-resolution.component.ts
import { Component, OnInit } from '@angular/core';
import { AbstractControl, FormControl, FormGroup, Validators } from '@angular/forms';
import { MatDialogRef } from '@angular/material/dialog';
import { AuthService } from '../../shared/services/auth.service';
import { ResolutionsService } from '../../shared/services/resolutions.service';
@Component({
selector: 'app-new-resolution',
templateUrl: './new-resolution.component.html',
styleUrls: ['./new-resolution.component.scss']
})
export class NewResolutionComponent implements OnInit {
uid: string
category_id: string
title: string
description: string
catId: string
categoryList = []
TitleControl: AbstractControl
DescriptionControl: AbstractControl
UserIdControl: AbstractControl
CategoryControl: AbstractControl
ResolutionFormGroup: FormGroup
constructor(public as: AuthService,
public rs: ResolutionsService,
public dialog: MatDialogRef<NewResolutionComponent>) { }
userid: string
ngOnInit(): void {
this.ResInit()
}
private ResInit() {
this.ResolutionFormGroup = new FormGroup({})
this.ResolutionFormGroup.registerControl('id',(this.UserIdControl = new FormControl('this',[Validators.required])))
this.ResolutionFormGroup.registerControl('category_id',(this.CategoryControl = new FormControl('',[Validators.required])))
this.ResolutionFormGroup.registerControl('title',(this.TitleControl = new FormControl('SUPER',[Validators.required])))
this.ResolutionFormGroup.registerControl('description',(this.DescriptionControl = new FormControl('',[Validators.required])))
}
This produces the desired output where my input has a placeholder of 'SUPER'. However, when I try to recreate this in another file, I get an entirely different result, and errors.
resolution-edit.component.html
(snippet: only showing one input as the others are identical)
<form formGroup='ResEditGroup'>
<mat-form-field>
<mat-label>Title</mat-label>
<input [FormControl]='TitleControl' matInput placeholder="Title" required/>
</mat-form-field>
The first thing I notice is that around my FormControl
I have '[]'. If I remove the brackets, my code will run without giving the error:
Can't bind to 'FormControl' since it isn't a known property of 'input'.
resolution-edit.component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { AbstractControl, FormControl, FormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
@Component({
selector: 'app-resolution-edit',
templateUrl: './resolution-edit.component.html',
styleUrls: ['./resolution-edit.component.scss']
})
export class ResolutionEditComponent implements OnInit {
ResEditGroup: FormGroup
TitleControl: AbstractControl
DescriptionControl: AbstractControl
description: string
title: string
descriptionInput: string
titleInput: string
constructor(
// @Inject(MAT_DIALOG_DATA) data
) {
// this.descriptionInput = data.description
// this.titleInput = data.title
}
ngOnInit(): void {
this.EditInit()
}
EditInit(): void{
this.ResEditGroup = new FormGroup({})
this.ResEditGroup.registerControl('title',(this.TitleControl = new FormControl('SUPERBAD',[Validators.required])))
this.ResEditGroup.registerControl('description',(this.DescriptionControl = new FormControl('',[Validators.required])))
}
}
Based on the comparison of both of my components, I would expect the input of the second component to display a placeholder of 'SUPERBAD', just as I had a placeholder of 'SUPER' in the first. However, in this case, I get no placeholder, except for what I declare directly inside the HTML input.
How do I get my second component to display 'SUPERBAD'?
Upvotes: 0
Views: 889
Reputation: 15083
Before we try to answer what is wrong with the code, lets try to refactor it to a shorter code.
import { Component, Inject, OnInit } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
**resolution-edit.component.ts**
@Component({
selector: 'app-resolution-edit',
templateUrl: './resolution-edit.component.html',
styleUrls: ['./resolution-edit.component.scss']
})
export class ResolutionEditComponent implements OnInit {
resEditGroup = this.fb.group({
title: ['SUPERBAD', [Validators.required]],
description: ['', [Validators.required]]
})
constructor(
private fb: FormBuilder,
// @Inject(MAT_DIALOG_DATA) data
) {
// this.descriptionInput = data.description
// this.titleInput = data.title
}
ngOnInit(): void {
}
}
With the above you can have resolution-edit.component.html
<form [formGroup]='ResEditGroup'>
<mat-form-field>
<mat-label>Title</mat-label>
<input formControlName='title' matInput placeholder="Title" required/>
</mat-form-field>
Below are the changes I have made.
FormBuilder
to generate my FormGroup
. With this I dont need to create a new FormFroup
and FormControl
using new
camelCase
FormGroup
using []
and for the controls I am passing formControlName
as a string. This is actually where you have a problem for you are passing in a FormGroup
but not binding to ResEditGroup
Upvotes: 1