subscribe to valueChanges from input FormControl in FormGroup

Solution 1:

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>

Solution 2:

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.