0

My goal is to scroll the ion-content component to top, when navigating to the page from some other selected pages. To achive this I am subscribing to the router's NavigationEnd events, and try to scroll to top inside the function provided to the subscribe method. When the scroll did not happen, I logged the IonContent's scroll element's scroll position inside the function, and it returned 0, even if the IonContent was not scrolled to top. I am assuming there is some conditions I am not aware of, and that is why I get the wrong value. What am I missing? I am using Ionic 6 with Angular 12.

Here is the after view init 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: I suppose this issue has somethng to do with where I call the scrollToTop method, or when I call it (IonContent may not be available at this point?.

Edit2: As StackoverBlows' answer states, and as I supposed the IonContent component is not available when NavigationEnd event fires. My solution is to get the state when NavigationEnd fires, then wait for the IonContent to be ready. I looks like this :

export class MyPage implements ViewWillEnter {
  constructor() {
    this.listennForScrollTopOnNavigation();
  }

  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();
      }
    });
  }
}
Viktor
  • 1
  • 3

1 Answers1

0

You are correct. ion-content is not available at that time. Remove the scrollToTop(), and add it in the ngAfterViewInit.

  • Sadly that would not solve my problem, because I need to check if I have to scroll to top each time when the user navigates to this page. The ionViewWillEnter/ionViewWillEnter lifecycle methods are not good either, because I need to check from which page the user is coming from (for that purpose I am using the state property of the navigation extras in the provided snippet). – Viktor Mar 01 '23 at 09:35