Sandeep Gupta
Sandeep Gupta

Reputation: 7250

NgForm.valueChanges is not being triggered when form input values are being changed programatically

In below code snippet, when I change the value of the variable (selectedBot) which is bound to form input (name="bot_id") programmatically ((click)="botSelected(bot) on <li>), form.valueChanges subscription callback handler is not triggered. However if I type in the input, this callback is being triggered as expected.

I have two question:

  1. Why is it happening?
  2. How to make it work?

app.component.html

<p>Selected bot: {{selectedBot.name}}</p>

<form #form="ngForm">

  <div class="btn-group" style="width: 100%">
    <div style="width: 100%">
      <input type="text" id="add" name="bot_id" ngModel placeholder="select a bot" [value]="selectedBot && selectedBot.name || ''">
      <i class="fa fa-angle-down center-vertical-absolute"></i>

    </div>
    <ul  class="dropdown-menu" role="menu" style="width: 100%; max-height: 30vh; overflow-y: scroll">
      <li role="menuitem" *ngFor="let bot of botList" (click)="botSelected(bot)"><a
        class="dropdown-item" [ngClass]="{'dropdown-item-active': selectedBot && selectedBot._id===bot._id}">{{bot.name}}</a>
      </li>
    </ul>
  </div>


</form>

app.component.ts

export class AppComponent implements OnInit {

  title = 'app';
  selectedBot;
  botList = [
    {'_id': 1, name: 'good bot'},
    {'_id': 2, name: 'bad bot'}
  ];
  @ViewChild('form') form: NgForm;


  constructor(private http: Http) {
  }
  ngOnInit() {
    this.form.valueChanges.subscribe((value) => {
      console.log('form data changed', value);
      /*NOT BEING TRIGGEERED WHEN ANY <li> IN <ul> is being clicked*/
    });
  }

  botSelected(bot) {
    this.selectedBot = bot;
  }

}

Upvotes: 1

Views: 1427

Answers (1)

user4676340
user4676340

Reputation:

Trigger the detection yourself.

botSelected(bot) {
  this.selectedBot = bot;
  this.form.updateValueAndValidity();
}

I would also recommend you use the correct function to set the values of the form. This means using [(ngModel)] and FormControl.prototype.setValue

EDIT Following this stackblitz, you should simply bind your inputs to a variable with [(ngModel)], and it should work.

Upvotes: 3

Related Questions