In my quest to scroll the ion-content component to the top upon navigating to the page from certain selected pages, I have implemented a solution using the router's NavigationEnd events. However, I have encountered an issue where the IonContent's scroll element returns a scroll position of 0 even when the content is not at the top. It seems that there may be some unknown conditions affecting this behavior. Can anyone help identify what I might be missing?
Below is the ngAfterViewInit hook where I attempted the scroll:
public ngAfterViewInit(): void {
this.router.events
.pipe(
filter(
(event) =>
event instanceof NavigationEnd &&
event.url.includes('/products') &&
!event.url.includes('/products/'),
),
)
.subscribe(async () => {
if (this.router.getCurrentNavigation()?.extras?.state?.scrollTop !== false) {
console.log((await this.ionContent.getScrollElement()).scrollTop); //0, even if ionContent is not scrolled to top
await this.ionContent.scrollToTop();
}
});
}
Edit: Upon further investigation and with reference to StackoverBlows' answer, it appears that the IonContent component may not be available when the NavigationEnd event fires. Therefore, my proposed solution involves retrieving the necessary state during the NavigationEnd event and waiting for the IonContent to be ready. This can be achieved as follows:
export class MyPage implements ViewWillEnter {
constructor() {
this.listenForScrollTopOnNavigation();
}
private ionContentReady$ = new Subject<void>();
public ionViewWillEnter(): void {
this.ionContentReady$.next();
}
private listenForScrollTopOnNavigation(): void {
const shouldScrollTop$ = this.router.events.pipe(
filter(
(event) =>
event instanceof NavigationEnd &&
event.url.includes('/products') &&
!event.url.includes('/products/'),
),
map(() => !!this.router.getCurrentNavigation()?.extras?.state?.scrollTop),
switchMap((shouldScrollTop: boolean) =>
this.ionContentReady$.pipe(map(() => shouldScrollTop)),
),
);
shouldScrollTop$.subscribe((shouldScrollTop) => {
if (shouldScrollTop) {
this.ionContent.scrollToTop();
}
});
}
}