sql_dummy
sql_dummy

Reputation: 745

execute a function after a div in ngIf?

When I click Button1 it would set varX, also "eventually" call loadValues(). But the function loadValues() accesses element <div id="foo" > , so loadValues should be called after <div id="foo" >, else it would result in Error:HTML container not found . How to execute a function after a div in ngIf?

-* my-component.ts *-

setVarX(){
  this.varX=true;
     
}
loadValues(){
}

-* my-component.hmtl *-

<button type="button" (click)="setVarX()">Button1</button>
        <ng-container *ngIf="varX">
            <div  id="foo" ></div>
            //loadValues() to be called now
        </ng-container>

I tried using ngAfterViewChecked but it is being called multiple (indefinite) times:

ngAfterViewChecked(){
    this.loadValues();      
}

Upvotes: 0

Views: 1072

Answers (2)

AliF50
AliF50

Reputation: 18849

You can have a utility of waitUntil that resolves a promise when an operation is completed.

import { interval } from 'rxjs';
import { take } from 'rxjs/operators';

export const waitUntil = async (untilTruthy: Function): Promise<boolean> => {
  while (!untilTruthy()) {
    await interval(25).pipe(take(1)).toPromise();
  }
  return Promise.resolve(true);
};
async setVarX(){
  this.varX=true;
  await waitUntil(() => !!document.getElementById('foo')); // wait until foo element is 
  // on screen before doing loadValues
  this.loadValues(); //-> but actually this function should be called after Div in *ngIf="varX"    
}

If you don't want to use document, you can use @ViewChild like so:

import { ViewChild } from '@angular/core';
....
@ViewChild('foo') foo: ElementRef; // declare variable

async setVarX(){
  this.varX=true;
  await waitUntil(() => !!this.foo); // wait until foo element is 
  // on screen before doing loadValues
  this.loadValues(); //-> but actually this function should be called after Div in *ngIf="varX"    
}

And your HTML will change to have a template variable on the foo div

<button type="button" (click)="setVarX()">Button1</button>
        <ng-container *ngIf="varX">
            <div  id="foo" #foo></div> // add #foo here
            //loadValues() to be called now
        </ng-container>

Upvotes: 1

saad shafiq
saad shafiq

Reputation: 162

I would get the this.loadValues() function out of the setVarX() function in .TS file and call it like this in HTML file

<div *ngIf="varX?loadValues():false">;</div>

Call a function from an *ngIf Angular 5

Upvotes: 0

Related Questions