18

I want to get one of my forms ("family") value if changed by subscribing but it seems something is wrong because I got nothing on my console's log.

import { Component , AfterViewInit } from '@angular/core';
import {FormGroup,FormBuilder} from '@angular/forms';
import {Observable} from 'rxjs/Rx';

@Component({
  selector: 'app-root',
  template: `<form [formGroup]="frm1">
<input type="text" formControlName="name" >
<input type="text" formControlName="family">
</form>
`,

})

export class AppComponent implements AfterViewInit{
  frm1 : FormGroup;

  constructor( fb:FormBuilder){
    this.frm1 = fb.group({
      name : [],
      family: []
    });
  }
  ngAfterViewInit(){
    var search = this.frm1.controls.family;
    search.valueChanges.subscribe( x => console.log(x));
  }
}
BinaryButterfly
  • 18,137
  • 13
  • 50
  • 91
M.J
  • 276
  • 1
  • 4
  • 13

3 Answers3

16

Use get method on form variable frm1. And use ngOnInit() instead of ngAfterViewInit()

ngOnInit() {  
   this.frm1.get('family').valueChanges.subscribe( x => console.log(x));
}
Amit Chigadani
  • 28,482
  • 13
  • 80
  • 98
  • Place the code within `ngOnInit()` and try. There is no reason to do within `ngAfterViewInit()` – Amit Chigadani Jun 17 '17 at 09:07
  • thanks now its working, may i know why AfterViewInit had problem!! – M.J Jun 17 '17 at 09:29
  • That was a workaround that I suggested, there is no reason to watch form control in`AfterViewInit`, since you are working on model-driven forms and you have all the form control names in place. So ideal place would be onInit(). – Amit Chigadani Jun 17 '17 at 09:41
  • I came across this issue because I am using this feature with a ngFor with async pipe, so it automagically subscribes and everything works just fine. Now I am using another one with a formControl and I forgot to subscribe :( Thanks for the tip though! – Sampgun Jul 15 '19 at 14:18
  • Prefer `rxjs` other features (`startWith` and `map` for example) rather than using `subscribe`: `this.control.valueChanges.pipe(startWith(''), map(opt => this.isMatch(name)));` – angellica.araujo Dec 19 '21 at 10:04
3

Try this:

import { Component , AfterViewInit, OnInit } from '@angular/core';
import {FormGroup,FormBuilder} from '@angular/forms';
import {Observable} from 'rxjs/Rx';

@Component({
selector: 'app-root',
template: `<h1>Hello World!</h1>
        <form [formGroup]="frm1">
        <input type="text" formControlName="name" >
        <input type="text" formControlName="family">
        </form>`})

export class AppComponent implements AfterViewInit, OnInit{ 

frm1 : FormGroup;

constructor( private formBuilder: FormBuilder){}

ngOnInit(): void {
    this.formInit();
    this.formSet();
}

formInit(): void {
    this.frm1 = this.formBuilder.group({
        name: [''],
        family['']
    })
}

formSet(): void {
    const editForm = {
        name: 'test-name',
        family: 'test familty',
    };
    this.frm1.patchValue(editForm) 
}

ngAfterViewInit(){  
this.frm1 .controls.family.valueChanges.subscribe(
       () => {
              console.log(this.frm1 .controls.family.value)
             }
        )
      }
}
Ketan Akbari
  • 10,837
  • 5
  • 31
  • 51
3

The question already uses subscribe but just in case somebody like me lands here after reading the title. valueChanges was also not working for me but for some other reason.

I was using material stepper and auto complete for my project. The sample code on their website, filters the data within map but it did not work.

this.filteredOptions = this.myControl.valueChanges.pipe(startWith(''), map(value => this._filter(value)));

However subscribing to the valueChange worked and filtered the data.

this.myControl.valueChanges.pipe(startWith('')).subscribe(value => this.filteredOptions = of(this._filter(value)));
Learning
  • 1,333
  • 16
  • 24