pTi
pTi

Reputation: 357

ngIf does not observe variable change

The following is an HTML code snippets where ngIf checks for forceAngle to be true, by default forceAngle is false. Once the button is clicked I call the ForceAngles() function and set forceAngle to true. The issue is once it is set to true, ngIf should check the status and show the correct template. At the moment I don't get the changes as expected. I'm new to this domain and surfed for hours on the internet to get a proper solution. I think I missed an Angular fundamental. Need expert support on this.

<ng-container matColumnDef="AssemblyAngle">
            <mat-header-cell *matHeaderCellDef [ngClass]='txt-wrapper'> Assembly Angles</mat-header-cell>
            <div *ngIf="forceAngle == 'true' ; else inputtemplate;">
              <mat-cell *matCellDef="let element">
                <span class="txt-inner">{{forceAngle}}</span>
              </mat-cell>
            </div>
            <ng-template #inputtemplate>

              <mat-cell *matCellDef="let element" class="txt-wrapper mat-header-cell">
               abc
              </mat-cell>
            </ng-template>
      </ng-container>

<button class="btn-secondary" (click)="ForceAngles()">Force Angles</button>

.ts file

ForceAngles() {
  this.forceAngle = 'true';
  
  this.loadCompressorOptimizeData();
  console.log(this.forceAngle);
  return this.forceAngle;
}

Upvotes: 4

Views: 8149

Answers (1)

Maciej Treder
Maciej Treder

Reputation: 12342

The problem is that nothing triggers Angular change detection mechanism. You have two ways to solve it:

First one

Implement mechanism which will trigger change detection using tick() method from ApplicationRef class:

import {ApplicationRef } from '@angular/core';

export class Component {
  constructor(private ref: ApplicationRef) {}

  ForceAngles() {
     this.forceAngle = 'true';

     this.loadCompressorOptimizeData();
     console.log(this.forceAngle);
     this.ref.tick();
     return this.forceAngle;
  }
}

Take a look at this answer for more information: Trigger update of component view from service - No Provider for ChangeDetectorRef

Another one

Use observable as forceAngle type, and async pipe in your template (async pipe triggers change detection automatically when a new value is pushed to observable).

Example .ts:

export class Component {
    forceAngle: Subject<boolean> = new Subject();

    someMethod(): void {
        this.forceAngle.next(true);
    }
}

and template:

<div *ngIf="(forceAngle | async) == true">some div</div>

Here you can find a nice article about change detection in Angular: https://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html

Upvotes: 7

Related Questions