How do I supress ngModelChange from firing when the component is being created (and therefore) populating my inputs with existing data?

465 views Asked by At

The basic premise of the problem is as follows:

I have a component with various (custom) inputs, when any of these input values change I do a HTTP call to an API endpoint to re-calculate what my audience reach is i.e. it's a Campaign system and as the user defines the audience demographic the audience 'reach' changes.

I trigger the call using ngModelChanges and this works very well.

However, my problem is when the component loads with existing data (from a previous save) it populates the inputs which causes ngModelChange to fire thereby causing my HTTP call to fire multiple times on page load.

Sample HTML:

<app-custom-input
        id="age-from"
        name="age-from"
        [(ngModel)]="audienceModel.ageFrom"
        [type]="'number'"
        (ngModelChange)="calcReach()"
></app-custom-input>
<app-custom-input
        id="age-to"
        name="age-to"
        [(ngModel)]="audienceModel.ageTo"
        [type]="'number'"
        (ngModelChange)="calcReach()"
></app-custom-input>

Note: my custom inputs do implement ControlValueAccessor

.ts file:

calcReach() {
    if (!this.loading$.getValue()) {
      const filters = {
        ...this.audienceModel,
        audienceFileId: this.campaignService.campaign.audienceFileId
      };
      this.calcAudienceReach$ = this.campaignService.calcAudienceReach(filters).subscribe((reach: number) => {
        console.log('calc audience reach: ', reach);
      });
    }
  }

As can be seen I did try using a loading indicator that I set to false at the end of my ngOnInit(), but the calls triggered by ngModelChange all happen after (or before?) OnInit.

I have an abstract component that my component implements where the loading indicator is defined as:

public loading$: BehaviorSubject<boolean> = new BehaviorSubject(true);

i.e. it gets set up with an initial value of true (in the abstract component) and only changed to false at the end of ngOnInit (in the actual component).

0

There are 0 answers