kcpr
kcpr

Reputation: 1105

Angular 2 Two-way Data Binding redundant setter call

I wanted to implement Two-way Data Binding in my component following this tutorial: https://blog.thoughtram.io/angular/2016/10/13/two-way-data-binding-in-angular-2.html . It works, but I discovered that after every change the setter is called twice when variables are 'bound'. The second one seems completely redundant. I noticed that the same problem appears in the tutorial - I modified the Plunker to show it: https://embed.plnkr.co/Pd39vssP2Cg4aSacFFlF/ .

I even noticed that the redundant setter call also happens when a variable value is changed omitting the setter - with something like this.counterValue++ for example.

I believe that the scenario goes like that:

  1. Component informs the watchers about the change by sending an event;
  2. The watcher changes the 'bonded' variable and informs that the variable changed on its side;
  3. The initial component receives the information that the variable changed and tries to change the variable to the same value.

The positive thing is that it does not go like that forever.
Still, in my opinion, the third point just should not take place.

I obviously could use simple if(this.counterValue !== val), but it doesn't seem like an elegant way of solving this issue. I believe that the redundant calls just should not be made in the first place.

Is there any way to avoid it or is it completely normal? Is it the correct way of implementing Two-way Data Binding or the example from the tutorial is just wrong?

Upvotes: 2

Views: 1012

Answers (1)

Günter Zöchbauer
Günter Zöchbauer

Reputation: 657781

You should just not emit an event in a method called by change detection.

The @Input() setter is called by change detection when the value is set by a binding.

This breaks one-way data flow, because a change in the parent, that is propagated to the child by change detection is propagated back to the parent because of this.counterChange.emit(this.counterValue);

You should rethink your architecture. A click event on a button should update the model, instead of a model change changing the model.

Moving the code that emits the event to the event handler should fix it

decrement() {
  this.counter--;
  this.counterChange.emit(this.counterValue);
}

Upvotes: 2

Related Questions