What is the use of onSameUrlNavigation property in Angular( versions greater than 5)
Asked Answered
G

6

21

Recently I have heard about a property called onSameUrlNavigation where you can set it to "reload". I have googled about it but there are not many articles which shows the use of that property. Can somebody help me with a real time example of where exactly we need to use that property.

@ngModule({
 imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: ‘reload’})],
 exports: [RouterModule],
 })
Grandioso answered 6/1, 2019 at 14:0 Comment(1)
Does this answer your question? How to reload the current route with the angular 2 routerSukey
M
16

For me, adding onSameUrlNavigation made absolutely no different to my Angular routing at all.

When trying to navigate from, say, /users:123 to /users:234, that option wouldn't allow me to refresh the page. My Angular pages have complex grids on them, and I specifically needed them to be disposed, and recreated, when I swap to a different user.

What did work (kill me now...) was to add this to my code.

let newRouterLink = '/users:123';
this.router.navigate(['/']).then(() => { this.router.navigate([newRouterLink ]); })

It's ugly, but it does the job....

Micrometeorite answered 1/12, 2020 at 15:50 Comment(1)
Mike, you may want to check out the routeReuseStrategy property of the Router class. Specifically, the shouldReuseRoute function of that property. It doesn't pertain to the original question so I won't go into it in more detail here, but I think it will accomplish what you are trying to do in a cleaner way.Groningen
C
15

onSameUrlNavigation configures how the router handles navigation to the current URL. By default, the router will ignore this navigation. However, this prevents features such as a "refresh" button. Use this option to configure the behavior when navigating to the current URL. Default is 'ignore'.by setting it to ‘reload’ you can navigate the current rout and trigger the router events again by setting it to 'ignore' if you navigate to same page it won't change the rout, see this example:

imports: [ BrowserModule, FormsModule, RouterModule.forRoot(routes, {
    // onSameUrlNavigation: 'ignore',
    onSameUrlNavigation: 'reload'
  }) ],
Cantabile answered 6/1, 2019 at 14:6 Comment(3)
What is the use of triggering the router events again?Grandioso
@Grandioso for e.g you want to refresh the page without changing the url and refresh the app, you rigger the NavigationEnd route event and for e.g re fetch the data or something else.Cantabile
Thank you. I got the gist of it :). medium.com/engineering-on-the-incline/…. This article is also a great example.Grandioso
F
11

I followed Joe Newton's hint and ended up with:

  1. Add { onSameUrlNavigation: 'reload' } to @NgModule (most likely in app.module.ts) like this:

@NgModule({ imports: [RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload' })] })

  1. In front of your this.router.navigate([PathName]) insert:

this.router.routeReuseStrategy.shouldReuseRoute = function() { return false; };

Tested on Angular 11.

Frontward answered 2/9, 2021 at 11:51 Comment(2)
this.router.routeReuseStrategy.shouldReuseRoute = function() { return false; }; was key for me, thanks so much for this!Checkmate
Note that the router property routeReuseStrategy is now deprecated. Suggested alternative is "Configure using providers instead: {provide: RouteReuseStrategy, useClass: MyStrategy}"Ion
U
5

Reloading Same Component by routerLink to Same Route in Angular

I would like to merge some of the information from some answers here into a single answer.

You can achieve reloading the same component from the same route by:

  1. Changing configuration in app-routing.module.ts
  2. Providing a RouteReuseStrategy (which returns false) in the component defining routerLink(s)

Example:

  1. app-routing.module.ts
//...
@NgModule({
  // See https://angular.io/api/router/Router#properties
  imports: [RouterModule.forRoot(routes, {
        // onSameUrlNavigation: 'ignore',  // default behavior
        onSameUrlNavigation: 'reload'
  })],
  exports: [RouterModule],
})
export class AppRoutingModule {}
  1. links.component.ts (arbitrary name, yours will be different)
export class LinksComponent implements OnInit {
// ...
  constructor(
    // ...
    private router: Router) { }

  ngOnInit(): void {
    //  ...
    // With the below line you can now reload the same component from the same route
    this.router.routeReuseStrategy.shouldReuseRoute = () => { return false; };
  }
}

📝 Supporting Docs

How to handle a navigation request to the current URL. One of:

  • 'ignore' : The router ignores the request.
  • 'reload' : The router reloads the URL. Use to implement a "refresh" feature.

Note that this only configures whether the Route reprocesses the URL and triggers related action and events like redirects, guards, and resolvers. By default, the router re-uses a component instance when it re-navigates to the same component type without visiting a different component first. This behavior is configured by the RouteReuseStrategy. In order to reload routed components on same url navigation, you need to set onSameUrlNavigation to 'reload' and provide a RouteReuseStrategy which returns false for shouldReuseRoute.

Considerations:

  • In our usage we only used static URLs; we haven't tested with dynamic URLs in our approach.
  • This example was tested using Angular 12.
Unitary answered 31/10, 2022 at 19:15 Comment(0)
R
1

RouteReuseStrategy. In order to reload routed components on same url navigation, you need to set onSameUrlNavigation to 'reload' and provide a **RouteReuseStrategy which returns false** for shouldReuseRoute.

https://angular.io/api/router/Router

Roxi answered 18/2, 2022 at 13:11 Comment(0)
S
0

I'd like to propose a different solution that uses both CustomRouteReuseStrategy and onSameUrlNavigation in order to force reload of the current route only when you need that behaviour and not always.

The solutions aims to forcing the reload of the current route by implementing a CustomRouteReuseStrategy that checks for a particular queryParam when requested to NOT reuse the current route explicitly. You can do that inside AppModule like this:

import { ActivatedRouteSnapshot, BaseRouteReuseStrategy, RouteReuseStrategy, RouterModule } from '@angular/router';


class CustomRouteReuseStrategy extends BaseRouteReuseStrategy {
  shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
    return !future.queryParamMap.get('$forceReload') &&
      (future.routeConfig === curr.routeConfig && isEqual(future.params, curr.params));
  }
}

@NgModule({
  // ... declarations and other module stuff
  providers: [
    {
      provide: RouteReuseStrategy,
      useClass: CustomRouteReuseStrategy
    }
  ]
})
export class AppModule { }

Like shown in the code the shouldReuseRoute checks whenever it can reuse the same route when both these conditions are true:

  • There is no $forceReload (with any value) inside queryParams
  • The current and future routeConfig are the same and share the same params (so in this case, with routes like this /devices/:param, /devices/1 is different from /devices/2)

So, whenever you need to reload the current component, you can simply navigate like this:

const currentUrl = new URL(this.router.url, document.location.origin);
// set force reload query param
currentUrl.searchParams.set('$forceReload', 'true');

this.router.navigateByUrl(
   // we can ignore URL origin and use only path and search
  `${finalRedirectPath.pathname}${finalRedirectPath.search}`, {
   onSameUrlNavigation: 'reload',
   replaceUrl: true
}).then(
// then stuff
).catch(
// catch stuff
)

In this snippet we use URL constructor (that necessarily needs an origin to work) to set our $forceReload param (and possibly preserves other query params) to a "truthy" value, the we navigate using only pathname and the resulting search string. The parameter onSameUrlNavigation: 'reload' ensures that shouldReuseRoute gets actually called always, the replaceUrl replaces the current url in order to avoid stacking this new route inside the page history.

Sukey answered 20/3 at 9:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.