Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

scrollPositionRestoration has several problems #24547

Closed
jnizet opened this issue Jun 16, 2018 · 114 comments
Closed

scrollPositionRestoration has several problems #24547

jnizet opened this issue Jun 16, 2018 · 114 comments
Assignees
Labels
area: router feature: under consideration Feature request for which voting has completed and the request is now under consideration feature Issue that requests a new feature
Milestone

Comments

@jnizet
Copy link
Contributor

jnizet commented Jun 16, 2018

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Performance issue
[x] Feature request
[x] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
[ ] Other... Please describe:

Current behavior

I started experimenting with the new scrollPositionRestoration feature in the RouterModule extra options. I expected scroll restoration to work by default when setting the property to 'enabled', but it doesn't. And the documentation has issues, too.

Expected behavior

The documentation says:

'enabled'--set the scroll position to the stored position. This option will be the default in the future.

So I naïvely thought that setting the flag to 'enabled' would be sufficient to restore the scroll position. But it isn't.

Indeed, the scroll event is fired, and the scroll position is restored, before the ngAfterViewInit hook of the activated component has been called. So the view of the component is not ready yet when the router tries to restore the scroll position (i.e. there is no way to scroll to the end of a long list, because the list isn't there yet).

And even if it was restored after the view is ready, that would only work if the activated component used a resolved guard to load the data.

So, the documentation should, IMHO, at least indicate that restoring the scroll position always requires to

  • explicitly intercept the Scroll event, and scroll imperatively after a delay. This can be done in a single place, but I don't see how to do that in a reliable way, since there is no way to know if the delay is sufficient for the data to have been loaded (but it would at least work if resolve guards are used consistently), or
  • explicitly intercept the Scroll event in each routed component, and imperatively scroll when the data has been loaded and the view has been rendered. This is not a trivial task.

I read the remaining of the documentation, which has examples about doing this kind of stuff (although it doesn't really say that they're required). But those examples are all incorrect.

Here's the first example:

    class AppModule {
     constructor(router: Router, viewportScroller: ViewportScroller, store: Store<AppState>) {
       router.events.pipe(filter(e => e instanceof Scroll), switchMap(e => {
         return store.pipe(first(), timeout(200), map(() => e));
       }).subscribe(e => {
         if (e.position) {
           viewportScroller.scrollToPosition(e.position);
         } else if (e.anchor) {
           viewportScroller.scrollToAnchor(e.anchor);
         } else {
           viewportScroller.scrollToPosition([0, 0]);
         }
       });
     }
    }

This example uses a Store service, which is not part of Angular (I guess it's part of ngrx). So that makes it hard to understand and adapt for those who don't use ngrx.

Besides, it doesn't compile, because a closing parenthesis is missing, and because e is of type Event, and not of type Scroll, and thus has no position property.

The second example is the following:

    class ListComponent {
      list: any[];
      constructor(router: Router, viewportScroller: ViewportScroller, fetcher: ListFetcher) {
        const scrollEvents = router.events.filter(e => e instanceof Scroll);
        listFetcher.fetch().pipe(withLatestFrom(scrollEvents)).subscribe(([list, e]) => {
          this.list = list;
          if (e.position) {
            viewportScroller.scrollToPosition(e.position);
          } else {
            viewportScroller.scrollToPosition([0, 0]);
          }
        });
      }
    }

It doesn't compile because it still uses an old, non-pipeable operator, and because, once again, e is of type Event, not Scroll.

But even after fixing the compilation errors, it doesn't work because the view hasn't been updated with the new list yet when viewportScroller.scrollToPosition(e.position); is called.

So the code would have to be changed to the following in order to compile and work as expected

    class ListComponent {
      list: any[];
      constructor(router: Router, viewportScroller: ViewportScroller, fetcher: ListFetcher) {
        const scrollEvents = router.events.filter(e => e instanceof Scroll);
        listFetcher.fetch().pipe(withLatestFrom(scrollEvents)).subscribe(([list, e]) => {
          this.races = list;
          const scrollEvent = e as Scroll;
          of(scrollEvent).pipe(delay(1)).subscribe(s => {
            if (s.position) {
              viewportScroller.scrollToPosition(s.position);
            } else {
              viewportScroller.scrollToPosition([0, 0]);
            }
          });
        });
      }
    }

I think that none of these solutions is really simple enough, though. Here are two ideas that could maybe make things easier:

  • only fire the Scroll event and try to restore the position after the ngAfterViewInit hook has been called. This should at least make things work when a resolve guard is used to load the list. Or when the list is available immediately.
  • for the other cases, allow to inject a service that the component could call when the list has been loaded. It would be up to this service to get the last scroll position or anchor, to wait until the view has been rendered, and then to restore the scroll position. It would ignore all but the first call after the component has been activated.

Minimal reproduction of the problem with instructions

Here's a repo illustrating the various issues and solutions presented above: https://github.com/jnizet/scrollbug. It's a standard angular-cli project. I can't run it in stackblitz unfortunately (probably because Stackblitz doesn't support the beta release of Angular).

What is the motivation / use case for changing the behavior?

First, the documentation should be fixed and made clearer

  1. it should not use ngrx
  2. it should contain examples that compile, and run as expected
  3. it should make it clear than simply setting the flag to 'enabled' is not sufficient to enable scroll restoration

Second, it should be way easier to make that feature work. See ideas above.

Environment


Angular version: 6.1.0-beta.1


Browser:
- [x] Chrome (desktop) version 67.0.3396.87
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [x] Firefox version 60.0.2 
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
@ngbot ngbot bot added this to the needsTriage milestone Jun 21, 2018
@jasonaden
Copy link
Contributor

Thanks for the detailed issue report! Great to get feedback on this new feature and hopefully get these things addressed quickly.

@mhevery
Copy link
Contributor

mhevery commented Jun 26, 2018

Closed by #20030

@mhevery mhevery closed this as completed Jun 26, 2018
@jnizet
Copy link
Contributor Author

jnizet commented Jun 26, 2018

@mhevery @jasonaden please reopen.

This issue is not about a missing scroll position restoration. It's precisely about the new scroll position restoration feature that was introduced in 6.1.0-beta.1.

And it thus can't be closed by #20030: this issue is precisely about several problems in the code and documentation introduced by #20030.

@mhevery
Copy link
Contributor

mhevery commented Jun 26, 2018

Sorry

@mhevery mhevery reopened this Jun 26, 2018
@coonmoo
Copy link

coonmoo commented Jul 9, 2018

I'd like to add in combination with Ionic 4 the ViewportScroller's Scroll event position property is always [0, 0]
See minimal repro: https://github.com/coonmoo/IonicScrollPosBug

@damienwebdev
Copy link

damienwebdev commented Jul 12, 2018

Just chiming in here, my initial expectation of this feature was the following:

  1. The "scrollPosition", specifically navigation to the point previously visited on prior pages, was going to be handled internally by angular with "sane" defaults that are simple to configure ('enabled'|'disabled'|'top' make perfect sense as outlined by @vsavkin).

To test this idea I tried the following as a simple use-case:

With scrollPositionRestoration set to enabled, I navigate halfway down "Page A" and click a link to "Page B". I expect to be at the top of "Page B", not at the height of the point I was at on "Page A" (this is what I currently experience). Next, if I scroll to another point on "Page B" and navigate back to "Page A", I should be at the halfway point I was at on "Page A" (Not at the other point I scrolled to on "Page B", what I currently experience).

This simple use-case doesn't seem to be resolved by the aforementioned #20030. Is that PR supposed to solve this use case?

But, just like @jnizet after upgrading a simple project to 6.1.0-rc1 it appears that these options don't actually do anything (maybe I'm missing something)?

I'm curious about the following:

  1. Are we expected to implement this scroll functionality on our own with the help of the ViewportScroller?
  2. What do the flags actually do out-of-the-box?

@damienwebdev
Copy link

damienwebdev commented Jul 12, 2018

Just leaving this here for all future visitors, as I did some debugging to determine why this wasn't working. For anyone who sees this in the future. If you have the following code in your stylesheet...

html,body {height: 100%}

This expected functionality will appear to be a bug for you.

Removing that style has a decent potential to fix this issue and make this PR do what was intended. Granted, removing that style may make a bunch of other things break, but that's a different problem.

Ninja edit:
It also appears that this seems to intermittently work with https://github.com/angular/material2

Working Version (My own personal anecdote):
I have a working app with material (which uses mat-sidenav) and all window.scroll variants work as expected.

Non-working version (as reported by @crisbeto ):
angular/components#11552

@jasonaden
Copy link
Contributor

@damienwebdev Thanks for that note on the body height. That very well could help quite a number of people

On the other things discussed in this issue, I've talked with @vsavkin about it and we're going to solve this in a couple ways. First is some documentation to make sure your use cases are discussed and solutions given for some of the common patterns. That documentation will be forthcoming.

Another is to fix an issue that was introduced some time ago where it's possible to have a NavigationEnd event fire before change detection. We need to change this so NavigationEnd happens after CD to make sure the page is actually rendered before trying to scroll.

@StefanRein
Copy link

StefanRein commented Jul 26, 2018

@jasonaden Could you tell, if following use case will be covered:

We are using perceived performance and intentionally are loading the data every time on component initialization, instead of caching, thus the app could be used with multiple devices at the same time.
Will there be a solution to tell the scroll restoration when the data of my component did load, so the view could be updated, elements could be created and the service finally would be able to scroll to the correct scroll position?

Thank you in forward.

@sorakthun
Copy link

What's the progress on this issue?

@ericmartinezr
Copy link
Contributor

explicitly intercept the Scroll event in each routed component, and imperatively scroll when the data has been loaded and the view has been rendered. This is not a trivial task.

This is a must after watching Jason's video about ng6.1 features where he says : [...] be aware on when and where you're rendering out your position.

Video: https://youtu.be/jNsbB8V9u0A?t=6m10s

@StefanRein
Copy link

StefanRein commented Jul 30, 2018

@mhevery (Edit: Sorry nevermind!)

I know one could preload all the data with Resolve from '@angular/router'. This would be fine and we could provide for each component an equal named class which could resolve all the needed data.
Then the scroll position restoration could work just as expected.
Usually this would also mean to show an overall spinner on the page, so the user would see there is something going on.

Another also very common practice is to use perceived performance. This is the way we decided to interact with preloading data. In our application we have a lot of times a list, which would show some grey boxes unless the data arrives and the list is shown.

As the component already is constructed and all the events are fired this would mean we would need to have the possibility to provide some asynchronous way to tell the data has been loaded for the scroll restoration service.

Do you see the possibility to provide a:

1. CustomScrollPositionRestorationStrategy or
2. another Lifecycle Hook

interface AfterContentReady {
    ngAfterContentReady(): Promise<boolean>;
}

I am also open for other ways. Maybe one would have some suggestions?

EDIT:
Okay, one way to go would be to store the value and call the scrollToPosition method of the ViewportScroller yourself.
E.g. Create an abstract class, from which you inherit and call a resolve method, every time you know your data is loaded and call in this abstracts class method, which implements this call this.viewportScroller.scrollToPosition(this.scrollPosition); - you get the idea.

Excerpt from:
https://github.com/Ninja-Squad/ninja-squad.github.com/pull/268/files
https://blog.ninja-squad.com/2018/07/26/what-is-new-angular-6.1/

export class PendingRacesComponent {
  scrollPosition: [number, number];
  races: Array<RaceModel>;

  constructor(route: ActivatedRoute, private router: Router, private viewportScroller: ViewportScroller) {
    this.races = route.snapshot.data['races'];
    this.router.events.pipe(
      filter(e => e instanceof Scroll)
    ).subscribe(e => {
      if ((e as Scroll).position) {
        this.scrollPosition = (e as Scroll).position;
      } else {
        this.scrollPosition = [0, 0];
      }
    });
  }

  ngAfterViewInit() {
    this.viewportScroller.scrollToPosition(this.scrollPosition);
  }

}

@akash-pal
Copy link

Whats the status on the issue? Hash anyone found a perfect solution/ when will this issue be fixed?

@StefanRein
Copy link

StefanRein commented Aug 20, 2018

One additional note I would like to mention here:
In some frameworks like IONIC 3 or other applications, the scrolling element is by default not the document body.

(I did workaround this by setting all parent elements until the body to position: static / relative (they were position: absolute before), which introduced other problems, e.g. with modal dialogs, backdrops or scroll bar issues with fixed elements on different OS with different settings..)

Feature request:

  • A possibility to register another scrolling element.
  • Handle multiple elements for scrolling. (router outlets + custom elements)

Potential problems

  • Multiple / nested router outlets
    • Possibility to set and get the scroll position for each one
      (Note: The default scrolling element could be the parent element of the router outlet element, but we would maybe need to register another one.)
  • Async between different router outlets and their scrolling position until the components are finished with loading and building the desired content (perceived performance strikes here again).
    • Note: Yes one could also resolve first the data. But how to handle perceived performance here? Maybe setting a component into a specific position while resolving the data?

@rankitbishnoi
Copy link

rankitbishnoi commented Aug 29, 2018

This feature breaks server side rendering with asp .net .
it is using Window while rendering on server.
https://github.com/angular/universal/issues/830#issuecomment-414239486

@twoheaded
Copy link

It's not quite clear, is there any way to set the scroll policy for certain routes?

@ouijan
Copy link

ouijan commented Sep 7, 2018

On Chrome, Using min-height doesn't break auto-scrolling and will force body t be at least screen height.
https://stackoverflow.com/questions/3740722/min-height-does-not-work-with-body

html {
    min-height: 100%;
    display: flex;
}
body {
    min-height: 100%;
    flex: 1;
}

@jasonaden
Copy link
Contributor

Thanks for the feedback so far on this issue. We're going to be making some minor improvements to the current implementation, but also will be adding some new documentation in the next few weeks to help with some of the scenarios you guys have been having trouble with. Thanks for the patience on this one.

@lnaie
Copy link

lnaie commented Sep 18, 2018

new insights...
looks like the feature is working when using the browser's Back button.

but when i use something like this, it doesn't:
this.router.navigate(['../'], { relativeTo: this.route });

could somebody explain why the above code is not producing the same behaviour as Location.back(), and what are the options?

@sarunint
Copy link
Contributor

@lnaie That is intended. This feature will work when use browser's navigating back. Redirecting to ../ is not navigating back, it's going up one level.

@petebacondarwin
Copy link
Member

I would be very happy to review and help merge updates to the docs that highlight these known issues, if you would like to send in some PRs.

@petebacondarwin
Copy link
Member

Oh and just to clarify a few things...

The P labels are not the same as the priority that I mentioned above. Once a piece of work is deemed complex enough it has to go into our team prioritization process amid many other tasks, of which quite a few are not even visible publicly.

And also, open issues are never closed by any bot. Only closed issues that have not received activity for a long time are locked. This is a common misconception but I am not sure how we can communicate that better.

@michaelurban
Copy link

@petebacondarwin Thanks for the reply. This response will swerve into off topic for this thread, but, of course I'd be happy to submit PRs.. My most pressing issue would be: #30477. Happy to discuss elsewhere.

@DeanPDX
Copy link
Contributor

DeanPDX commented Oct 23, 2021

@michaelurban the workaround I posted above (or a variation on that) has been working for me in a production app for over a year. The issue isn't that the documentation is wrong, but rather that the BrowserViewportScroller implements ViewportScroller by default in a way that assumes you're scrolling the window, not a scrolly div or the like. I don't think there is anything incorrect about the documentation.

To me, this feels like a "recipe" for lack of a better term. Or it could be solved with something similar to the Common Routing Tasks section in the router guide. Because implementing your own ViewportScroller to suit your needs is a trivial task; the problem is that knowing you need to implement it in many cases is not obvious. @petebacondarwin I'd be happy to take a stab a PR for updating the documentation with some examples of when/how/why to implement ViewportScroller. I'm just not sure where it fits in the documentation. I took a cursory glance at the current docs and didn't see an obvious spot for it.

@michaelurban
Copy link

michaelurban commented Oct 23, 2021

@DeanPDX Yes, as I previously stated, in this case the documentation is incomplete/oversimplified rather than incorrect.

The feature also needs some work aside from the documentation but, the core issue is: Sometimes in Angular things are not as simple or as solid the documentation would have you believe. If a feature has several caveats, special cases, or, has not worked for years (as in #30477), that should be spelled out clearly in the docs.

@hiepxanh
Copy link
Contributor

we should remove filter((e:Event) => to filter((e) => to prevent type checking error.
and I have to change scroll to have setTimeout:

setTimeout(() => {
          e.position && this.viewportScroller.scrollToPosition(e.position);
        }, 300);

to prevent scroll trigger too fast, before ngOnInit. I dont know why my component both reconstruct and re run ngOnInit on back. I just back only. and it cannot run fast enough

scrollRestoration() {
    // https://angular.io/api/router/ExtraOptions#scrollPositionRestoration
    this.router.events.pipe(filter((e): e is Scroll => e instanceof Scroll)).subscribe((e) => {
      if (e.position) {
        // console.log('e.position scrolling....', e);
        // backward navigation
        setTimeout(() => {
          e.position && this.viewportScroller.scrollToPosition(e.position);
        }, 300);
      } else if (e.anchor) {
        // console.log('e.position anchor!!', e);
        // anchor navigation
        this.viewportScroller.scrollToAnchor(e.anchor);
      } else {
        // forward navigation
        // console.log('e.position scroll top on new navigation', e);
        this.viewportScroller.scrollToPosition([0, 0]);
      }
    });

@TheJLifeX
Copy link

TheJLifeX commented Mar 15, 2022

Hi everybody,

concerning this issue, you could have a look at NgxScrollPositionRestoration. A library for scroll position restoration in Angular.

The library supports scroll position restoration on:

  • Any scrollable element (for example: .mat-sidenav-content in case you are using Angular Material Sidenav)
  • Lazy loading content
  • Named router-outlets (multiple router-outlets)
  • Child routes (nested router-outlets)
  • Backward and forward navigation

View the demo

Compatibility

Angular version Compatible with (tested on)
Angular 6 Yes
Angular 7 Yes
Angular 8 Yes
Angular 9 Yes
Angular 10 Yes
Angular 11 Yes
Angular 12 Yes
Angular 13 Yes

@HARSHITHASAI-A
Copy link

HARSHITHASAI-A commented Mar 22, 2022

Hello everyone,

I have the similar issue. I have used mat-paginator for pagination and on the new/next page click the scrollbar should reset to top for the page change event. Instead it is shortening, could any one please help me with this. @TheJLifeX @hiepxanh

.html file
Screenshot 2022-03-22 at 5 22 29 PM

.ts file - page method
Screenshot 2022-03-22 at 5 23 34 PM

atscott added a commit to atscott/angular that referenced this issue May 31, 2022
This makes a small update to the example so that it shows a use-case
that's not already covered by the 'enabled' option. The existing example
would get identical behavior to `scrollPositionRestoration: 'enabled'`
with `anchorScrolling: 'enabled'`.

The updated example shows a use-case for when custom scrolling _would_
be needed. For example, when data is fetched because it is not available
immediately or through a resolver. This is one of the cases described in angular#24547

This update is sufficient to address all of the documentation problems
noted in the aforementioned issue. Another fix should be made to address
the problem that scroll restoration needs to be delayed until after CD
has run so the update block of the activated component's template is
run.
atscott added a commit that referenced this issue Jun 1, 2022
This makes a small update to the example so that it shows a use-case
that's not already covered by the 'enabled' option. The existing example
would get identical behavior to `scrollPositionRestoration: 'enabled'`
with `anchorScrolling: 'enabled'`.

The updated example shows a use-case for when custom scrolling _would_
be needed. For example, when data is fetched because it is not available
immediately or through a resolver. This is one of the cases described in #24547

This update is sufficient to address all of the documentation problems
noted in the aforementioned issue. Another fix should be made to address
the problem that scroll restoration needs to be delayed until after CD
has run so the update block of the activated component's template is
run.

PR Close #46201
atscott added a commit that referenced this issue Jun 1, 2022
This makes a small update to the example so that it shows a use-case
that's not already covered by the 'enabled' option. The existing example
would get identical behavior to `scrollPositionRestoration: 'enabled'`
with `anchorScrolling: 'enabled'`.

The updated example shows a use-case for when custom scrolling _would_
be needed. For example, when data is fetched because it is not available
immediately or through a resolver. This is one of the cases described in #24547

This update is sufficient to address all of the documentation problems
noted in the aforementioned issue. Another fix should be made to address
the problem that scroll restoration needs to be delayed until after CD
has run so the update block of the activated component's template is
run.

PR Close #46201
atscott added a commit that referenced this issue Jun 1, 2022
This makes a small update to the example so that it shows a use-case
that's not already covered by the 'enabled' option. The existing example
would get identical behavior to `scrollPositionRestoration: 'enabled'`
with `anchorScrolling: 'enabled'`.

The updated example shows a use-case for when custom scrolling _would_
be needed. For example, when data is fetched because it is not available
immediately or through a resolver. This is one of the cases described in #24547

This update is sufficient to address all of the documentation problems
noted in the aforementioned issue. Another fix should be made to address
the problem that scroll restoration needs to be delayed until after CD
has run so the update block of the activated component's template is
run.

PR Close #46201
@TheJLifeX
Copy link

Hi @HARSHITHASAI-A,
Since you are using a paginator, you should know that scroll position restauration only happens on popstate navigation (when you click on the browser back- or forward button). When you click on the paginator-buttons (even when you return to the previous page) you create an imperative navigation (with this.router.navigate(…)).
To manually trigger a popstate navigation you can use the following functions:

import { Location } from '@angular/common';

class SomeComponent {

  constructor(private location: Location) { }

  goBack() {
    this.location.back(); // See: https://angular.io/api/common/Location#back
  }

  goForward() {
    this.location.forward(); // See: https://angular.io/api/common/Location#forward
  }
}

If you are using NgxScrollPositionRestoration, you can import it like this (with debug set to true), to debug if something is not working as expected:

    NgxScrollPositionRestorationModule.forRoot({
      debug: true
    })

I hope this can help you.

atscott added a commit to atscott/angular that referenced this issue Sep 27, 2022
…e rendered

Currently, the scroll event is fired immediately after the
`NavigationEnd`. However, this is problematic because a change detection
has not been able to run, meaning that Angular will not yet have run the update
block of the component templates being rendered as part of the navigation.

This change delays the scroll event using a `setTimeout`, which will
allow Angular's change detection to run before the scroll restoration is
performed.

fixes angular#24547
atscott added a commit to atscott/angular that referenced this issue Sep 27, 2022
…e rendered

Currently, the scroll event is fired immediately after the
`NavigationEnd`. However, this is problematic because a change detection
has not been able to run, meaning that Angular will not yet have run the update
block of the component templates being rendered as part of the navigation.

This change delays the scroll event using a `setTimeout`, which will
allow Angular's change detection to run before the scroll restoration is
performed.

fixes angular#24547
atscott added a commit to atscott/angular that referenced this issue Sep 27, 2022
…e rendered

Currently, the scroll event is fired immediately after the
`NavigationEnd`. However, this is problematic because a change detection
has not been able to run, meaning that Angular will not yet have run the update
block of the component templates being rendered as part of the navigation.

This change delays the scroll event using a `setTimeout`, which will
allow Angular's change detection to run before the scroll restoration is
performed.

fixes angular#24547
atscott added a commit to atscott/angular that referenced this issue Oct 17, 2022
…e rendered

Currently, the scroll event is fired immediately after the
`NavigationEnd`. However, this is problematic because a change detection
has not been able to run, meaning that Angular will not yet have run the update
block of the component templates being rendered as part of the navigation.

This change delays the scroll event using a `setTimeout`, which will
allow Angular's change detection to run before the scroll restoration is
performed.

fixes angular#24547
Feature Requests automation moved this from Needs Project Proposal to Closed Oct 19, 2022
dylhunn pushed a commit that referenced this issue Oct 19, 2022
…e rendered (#47563)

Currently, the scroll event is fired immediately after the
`NavigationEnd`. However, this is problematic because a change detection
has not been able to run, meaning that Angular will not yet have run the update
block of the component templates being rendered as part of the navigation.

This change delays the scroll event using a `setTimeout`, which will
allow Angular's change detection to run before the scroll restoration is
performed.

fixes #24547

PR Close #47563
@Erbenos
Copy link
Contributor

Erbenos commented Oct 31, 2022

It seems that af8afee addresses some change detection portion of this issue, though I am not if that anyhow resolves the issue for those people that don't have html/body their scrollable element. It would be nice if we could pass either a specific selector for scrollable container ourselves or some kind of custom strategy for resolving the component dynamically ourselves.

nouraellm pushed a commit to nouraellm/angular that referenced this issue Nov 6, 2022
…e rendered (angular#47563)

Currently, the scroll event is fired immediately after the
`NavigationEnd`. However, this is problematic because a change detection
has not been able to run, meaning that Angular will not yet have run the update
block of the component templates being rendered as part of the navigation.

This change delays the scroll event using a `setTimeout`, which will
allow Angular's change detection to run before the scroll restoration is
performed.

fixes angular#24547

PR Close angular#47563
@Goretzky
Copy link

I have a simple Angular 14 app where everything is served prerendered on S3. Angular's scrollPositionRestoration: 'enabled' works for my web app as long as the screen is large. But on a mobile phone screen scrollPositionRestoraiton stops working. Anyone know why this would happen?

I ran into problems trying DeanPDX's solution, which has an Angular 9 demo. For example, I wasn't able to import eeinject in the app.module.ts. Was anyone able to get this solution working in Angular 14? If so, what changes did you have to make?

NgxScrollPositionRestoration is only compatible with Angular 13 and earlier, or did someone get this to work in Angular 14?

Small screen size issue happened in Chrome browser on a large monitor with browser shrunk down, on a chromebook again with the browser shrunk down to mobile phone size, and an iphone using Chrome browser and Safari. I also tried anchorScrolling as a solution but had the same result: works on wide screen but not on cell phone sized screen.

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Dec 13, 2022
trekladyone pushed a commit to trekladyone/angular that referenced this issue Feb 1, 2023
…e rendered (angular#47563)

Currently, the scroll event is fired immediately after the
`NavigationEnd`. However, this is problematic because a change detection
has not been able to run, meaning that Angular will not yet have run the update
block of the component templates being rendered as part of the navigation.

This change delays the scroll event using a `setTimeout`, which will
allow Angular's change detection to run before the scroll restoration is
performed.

fixes angular#24547

PR Close angular#47563
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: router feature: under consideration Feature request for which voting has completed and the request is now under consideration feature Issue that requests a new feature
Projects
No open projects
Development

Successfully merging a pull request may close this issue.