I have an Angular component where I want to use scrollIntoView when the route changes. Here’s the relevant code snippet from my component:
@ViewChild('structure') structure: ElementRef | undefined;
legacyRoute: string = '';
constructor(private apiService: ApiService, private router: ActivatedRoute, private route: Router, private cdRef: ChangeDetectorRef) { }
ngAfterViewInit() {
this.router.paramMap.subscribe(params => {
this.legacyRoute = params.get('id') || '';
console.log("checking legacy after param map subscription", this.legacyRoute);
setTimeout(() => {
if (this.legacyRoute && this.structure && this.structure.nativeElement) {
console.log("Running scrollIntoView", this.legacyRoute, this.structure, this.structure.nativeElement);
this.structure.nativeElement.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'start' });
}
}, 1000)
});
}
Problem:
The scrollIntoView function works correctly on page refresh, but not when Angular routes change. I’ve added a setTimeout to delay the function, which makes it work, but I understand this is not a robust solution.
What I’ve tried:
-
Removing the setTimeout results in scrollIntoView not functioning properly on route changes.
-
Ensuring that this.structure.nativeElement is valid before calling scrollIntoView.
-
Using ngAfterViewChecked() instead of ngAfterViewInit()
Expected Behavior:
I expect scrollIntoView to execute correctly when navigating to a different route within the Angular application, without relying on a setTimeout.
Additional Context:
- Angular version:
"dependencies": {
"@angular/animations": "^17.3.0",
"@angular/cdk": "^17.3.9",
"@angular/common": "^17.3.0",
"@angular/compiler": "^17.3.0",
"@angular/core": "^17.3.0",
"@angular/forms": "^17.3.0",
"@angular/platform-browser": "^17.3.0",
"@angular/platform-browser-dynamic": "^17.3.0",
"@angular/platform-server": "^17.3.0",
"@angular/router": "^17.3.0",
"@angular/ssr": "^17.3.7",
"@ngrx/store": "^17.2.0",
"express": "^4.18.2",
"force": "^0.0.3",
"primeicons": "^7.0.0",
"primeng": "^17.17.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.3"
}
- structure is a ViewChild or ElementRef pointing to the DOM element where scrollIntoView should be applied.
<– something like <div #structure id=”structure”> –>
My title
Since I’m new to Angular, I want to ensure I haven’t overlooked anything important. Your assistance means a lot to me, and I sincerely appreciate your time and help. Thank you in advance!