1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. Anuncie Aqui
    Anuncie aqui você Também: fdantas@4each.com.br

check if DOM element under *ngIf is already rendered

Discussão em 'Angular' iniciado por olha-krayevska, Setembro 26, 2024.

  1. In my Angular 14 App I've got component with canvas in template. Whole template is under *ngIf checking if data was emitted by Observable. I need to create Chart using data from Observable and canvas reference which I get with @ViewChild. The problem is, when I got data in Observable pipe, canvas element is not rendered yet. I can use setTimeout in Observable pipe and it will work but I don't want to use it, so I've been looking for better solution and finally I've come up with one below.

    1 I've got canvas @ViewChild, BehaviorSubject canvasLoaded$ with initial value false, and canvasLoadedSubscription:

    @ViewChild('canvas') canvas!: ElementRef;
    canvasLoaded$: BehaviorSubject<boolean> = new BehaviorSubject(false);
    canvasLoadedSubscription!: Subscription;


    2 I've got method subscribeToCanvasLoaded where I subscribe to canvasLoaded$ saving subscription in canvasLoadedSubscription, and call renderCharts if canvasLoaded$ emits true:

    subscribeToCanvasLoaded(data: any): void {
    this.canvasLoadedSubscription = this.canvasLoaded$
    .pipe(filter(Boolean))
    .subscribe(() => this.renderCharts(data));
    }


    3 in data$ pipe I call subscribeToCanvasLoaded method passing data:

    this.data$ = this.dataService.data$.pipe(
    filter(Boolean),
    tap((data) => {
    if(data.length) {
    this.subscribeToCanvasLoaded(data)
    }
    })
    );


    4 in ngAfterContentChecked if I already can access canvas and if canvasLoaded$ still false I set it to true and unsubscribe from canvasLoadedSubscription:

    ngAfterContentChecked(): void {
    if(this.canvas && !this.canvasLoaded$.value) {
    this.canvasLoaded$.next(true);
    this.canvasLoadedSubscription.unsubscribe();
    }
    }


    this way I don't have to save data in component, it goes straight to template where I use async pipe, I don't have to use seTimeout() and I know for sure when canvas is in DOM.

    Now I'm wondering how bad is it and why)

    Continue reading...

Compartilhe esta Página