How do I start a function from within a *ngIf directive?

Viewed 328

I am new to Angular.

How do I start a function from within a *ngIf= directive, when certain criterions are NOT met?

Note that in my code, below, the first *ngIf successfully displays a {{tab1TrxMessage}} message if a tab1TrxMessage is available.

<div (click)="clearForm(1)" *ngIf="tab1TrxId" class="sign-btn text-center fixedNotification" style="margin-top: 20px">
    <a class="btn btn-lg text-white" [ngClass]="trx1Btn">
       <span *ngIf="tab1TrxMessage">{{tab1TrxMessage}}</span>
       <span *ngIf="!tab1TrxMessage && tab1TrxStatus != 'Success'" "testing123()">Failed</span>
    </a>
</div>

However, in the second *ngIf directive, I if there isn't tab1TrxMessage message and the tab1TrxStatus status isnt of satus Success, I'd like this function testing123() to fire up!

Can anyone kindly help me understand how to achieve this as the current doesnt work.

Following is the .ts file content:

testing123(){
    console.log("Testing if this works!")
}
2 Answers

Move it to method

messageFailed() {
  if(!this.tab1TrxMessage && this.tab1TrxStatus != 'Success') {
    this.testing123();
    return true;
  }

  return false;
}

And call method in template condition

<span *ngIf="messageFailed()">Failed</span>

Do not make calls to functions from within Angular templates. why not?

Angular evaluates the expressions contained within templates (including ngIf) each and every change detection cycle. At best, what you would be trying to do would depend upon the side-effect of a change detection cycle taking place. At worst, it would cause your change detection to slow down, possibly making your app less responsive or much more processor-intensive.

The ngIf directive is intended to display a section of HTML if the condition is true. Optionally, you can specify a <ng-template> to display if the condition is false (ngIf-Else). To ensure your program is stable and usable in the future, evaluation of a condition should never change the state of a program.

Where should this logic go?

If you need to have something happen in response to an input variable, the appropriate place to do that would be on the setter.

So, in this example, you have two properties: tab1TrxMessage and tab1TrxStatus. The code below depends on whether you have private backing fields, so I'll leave that part to you, but here's what it would look like.

get tab1TrxMessage() { return this._tab1TrxMessage; } // assumes private backing field  
set tab1TrxMessage(v) {
  this._tab1TrxMessage = v;
  this.performCheck();
}


get tab1TrxStatus() { return this._tab1TrxStatus; } // assumes private backing field  
set tab1TrxStatus(v) {
  this._tab1TrxStatus= v;
  this.performCheck();
}

private performCheck(): void {
  if(!this.tab1TrxMessage && this.tab1TrxStatus != 'Success') {
    // note on the above - recommend defining 'Success' in an enum.
    this.testing123();
  }
}
Related