In Angular 4, I\'m trying to subscribe to the valueChanges of a FormControl. Neither of the versions below is working. I\'m not seeing any errors. The form.value JSON is upd
I think you are missing some thing here with formGroup
and formControlName
you should do:
myForm: FormGroup;
firstName = '';
lastName = '';
on ngOnInit
this.myForm = this.formBuilder.group({
firstName: [this.firstName],
lastName: [this.lastName]
});
this.myForm.controls['firstName'].valueChanges.subscribe(value => {
console.log(value);
});
and In HTML
<form [formGroup]="myForm">
...
<input name="firstName" [(ngModel)]="firstName" formControlName="firstName" placeholder="enter name"/>
<input name="lastName" [(ngModel)]="lastName" formControlName="lastName" placeholder="enter last name"/>
...
</form>
I gave up on FormGroup and FormBuilder and just used
HTML:
<input mdInput [formControl]="firstName">
App class:
firstName = new FormControl();
ngOnInit:
this.firstName.valueChanges.subscribe(value => {
console.log('name has changed:', value)
});
My test is currently broken with the error "No provider for NgControl" but I'll work on that next. Update: I just needed to import ReactiveFormsModule in the TestBed
You are missing some crucial things in your code. First of all, what you are trying to subscribe to, doesn't exist. You have not marked that field to be a formcontrol, so Angular doesn't know to subscribe to that. You need to mark formControlName="firstname"
to let Angular know it's a form control.
Also you are missing marking your form as a form group, it should be:
<form [formGroup]="myForm">
Using ngModel
in forms is discouraged, the ngModel
directive isn't even included in ReactiveFormsModule
. I have also noticed that it often causes issues when used together with reactive forms. You have the form controls there to replace the use of ngModel
, so drop it and make use of the form controls, since they are already in place! :)
Then I would instead of using valueChanges
just use some change event instead in the template, but it's up to you.
So, the build of the form should look like this:
this.myForm = this.formBuilder.group({
firstname: [''],
lastname: ['']
})
// I like to use variables
this.firstNameCtrl = this.myForm.get('firstname')
// as mentioned, like to use change event:
logValue(value) {
console.log(value)
}
The template would then look like this:
<form [formGroup]="myForm">
<md-input-container>
<input mdInput formControlName="firstname"
(keyup)="logValue(firstNameCtrl.value)" />
</md-input-container>
<md-input-container>
<input mdInput formControlName="lastname"/>
</md-input-container>
</form>
So as mentioned use the form controls. If you need an initial value, set them in the build of the form. You have all values in your form object and you can access the values if you wish.