angularngfortransclusion

constructor being called duplicate in *ngFor due to @ViewChild


I have an angular 2 component I have created, which I am using in an *ngFor directive and it appears that the constructor is being called twice for each instance.

So if I have 2 records returned to my collection, the constructor of my component is entered 4 times. If I have three the constructor is fired 6 times.

This is causing issues for me as I am subscribing to RxJs observables in the constructor therefore my events are being acted upon duplicate so when handling a delete event, code is attempting to delete same record multiple times so fails after first (successful) call.

Code structure is as so:

Outer most component

<div class="list-row-container" *ngFor="let holiday of holidays">
  <div style="border:1px; border-style: solid; margin: 5px;">
  <div style="margin: 5px;">
  <extended-inline-edit actionClass="fa-calendar" 
  [entityId]="holiday.id">
        <holiday-view-body view-body [holiday]="holiday"></holiday-view-
  body>
        <holiday-edit-body edit-body [holiday]="holiday" [venueId]="venueId" 
  [year]="year"></holiday-edit-body>
      </extended-inline-edit>
    </div>
  </div>
</div>

My component which is affected is the holiday-edit-body component, which is being transcluded into my extended-inline-edit component hosting it (don't know if transclusion would affect number of times constructor is fired?)

My collection is populated in the ngOnInit of the outer most component, holidays.ts as below:

  ngOnInit() {

    this.holidayService.getVenueHolidayInheritanceIndicator(this.venueId).then((data) => {
      this.inheritFromAccount = data.sameAsAccount;
      if (this.inheritFromAccount === false) {
        this.loadVenueHolidays();
      } else {
        this.loadAccountHolidays();
      }
    });
  }

  loadVenueHolidays() {
    this.holidayService.getVenueHolidays(this.venueId, this.year).then((data) => {
      this.holidays = data;
    });
  }

Solution

  • My problem seems to have been caused by a component further up the hierarchy having a reference to my "Parent" component with a @ViewChild attribute and in this code, a call was being made to refresh my collection so 2 holidays were retrieved from DB and my components were created as per the *ngFor, then this refresh call was bringing two holidays again and *ngFor firing again (I'm presuming????) so my events were wired up twice.

    I got rid of the call to refresh BUT this would still happen upon other events so unsubscribed in the ngOnDestroy method of my component as below to ensure no erroneous subscriptions knocking around! (Subscriptions set up from constructor still)

      ngOnDestroy() {
        this.clearDownSubscriptions();
      }
    
      clearDownSubscriptions(){
        this.deleteHolidaySubscription.unsubscribe();
        this.asideCloseSubscription.unsubscribe();
        this.scheduleSavedSubcription.unsubscribe();
        this.saveHolidaySubscription.unsubscribe();
        this.editToggledSubscription.unsubscribe();
        this.performActionSubscription.unsubscribe();
      }