1

I have a very small basic angular (14) SPA with a couple of routes. I'm using @ViewChild to get the coordinates of a particular element:

 @ViewChild('testElement', { static: true }) testElement!: ElementRef<HTMLDivElement>;

and then

ngAfterViewInit(): void {
    var position = this.fadeInText.nativeElement.getBoundingClientRect();
    var y = position.top; // (etc)
}

What I've noticed is that I get incorrect y values if I return to the route after going to another route.

However, if I check the positions again in ngAfterViewChecked after it has fired at least once before, I get the correct position values.

Is there a better way to handle this? I can't seem to find any other documentation on this issue.

Many thanks!

aburton
  • 11
  • 1
  • Did you try `ChangeDetectorRef`? – Mohamed Karkotly Jul 17 '22 at 02:51
  • @Mohamed.Karkotly - No, I'm not sure how that would work in this context, or what event we'd attach it to that isn't already firing. I would have expected that the element position would have settled afterViewInit, but it doesn't until the afterView is checked twice. Thanks for the response! – aburton Jul 17 '22 at 03:07

1 Answers1

0

It can takes a moment for the DOM to render completely. A short setTimeout will probably work

ngAfterViewInit(): void {
    setTimeout(() => {
       this.positionCalculations()
    }, 20)
}

You could also use an RxJS timer(20) rather than setTimeout, that way you can add a takeUntil in case routes change very fast

Drenai
  • 11,315
  • 9
  • 48
  • 82
  • Appreciate the response. I'm hoping for a more event driven solution as delaying the calculation may work most of the time, but doesn't guarantee the desired result. – aburton Jul 17 '22 at 18:47
  • @aburton Did you go with `setTimeout` in the end or find a better way? – Drenai Aug 12 '22 at 07:34
  • I ended up using my original method, I'm not sure I see an advantage one way or the other between yours and mind. Both seem like they're trying to get around a problem without an elegant solution. – aburton Aug 22 '22 at 17:05