MPP
MPP

Reputation: 65

Navigate to a fragment of a **different** (not the same) page/component in Angular

On click of a link, I would like to navigate to a fragment of a different page/component. I have not been able to achieve this even though trying multiple things:

Link:

<a routerLink="/main/dash" fragment="dir">View</a>

The destination html/template:

<!-- Other elements -->

<app-dir id="dir"></app-dir>

Router configuration:

{
   path: 'main',
   component: LayoutComponent,
   children: [{
      path: 'dash',
         loadChildren: () => import('src/app/features/dash/dash.module').then(m => m.DashModule),
         canActivate: [AuthGuard]
   }]

   // Other code
}
   
// Other code

imports: [RouterModule.forRoot(appRoutes, { useHash: true, anchorScrolling: 'enabled', onSameUrlNavigation: 'reload' })],

On click of the "View" link, the system navigates to the /main/dash path/page/component, but it does not scroll to the fragment in the first go. Once I am on the homepage, when I click on the same navigation link (View - which resides in header), it scrolls to the fragment.

I.e. AnchorScrolling works when I am already on the same page/component, but not if the source is a different page/component.

I also tried using (click) & this.router.navigate() instead of using routerLink - but the result is same.

I do use HashLocationStrategy.

Any help would be appreciated.

Thanks!

Update:

After digging even deeper, Fragment Routing after Page Load Angular is the exact problem I am facing. It seems there is no solution available yet?: https://github.com/angular/angular/issues/30139

Upvotes: 6

Views: 3138

Answers (1)

Atanas Karamanov
Atanas Karamanov

Reputation: 31

I had the same problem. Interesting that once navigating to the page with fragments it scrolls to the bottom. Here is the solution that worked for me:

In component that contains fragments:

/*...imports*/

export class ComponentWithFragmentsInTemplate implements OnInit, AfterViewInit {
  private fragment: string;

  constructor(private route: ActivatedRoute) {
  }

  ngOnInit() {
    this.route.fragment.subscribe(fragment => {
      this.fragment = fragment;
    });
  }

  ngAfterViewInit(): void {
    setTimeout(() => { //I needed also setTimeout in order to make it work
      try {
        document.querySelector('#' + this.fragment).scrollIntoView();
      } catch (e) {
      }
    });
  }

Without empty setTimeout() it doesn't work for me.

Upvotes: 3

Related Questions