The onSameUrlNavigation property defines what the router should do if it receives a navigation request to the current URL. By default, the router will ignore this navigation. However, this prevents features such as a “refresh” button.
There are many ways by which you can get a current Route or URL in Angular. You can use the router service, location service or window object to get the path. You can also listen to changes to URL using the router event or URL change event of the location service.
ActivatedRoutelink. Provides access to information about a route associated with a component that is loaded in an outlet. Use to traverse the RouterState tree and extract information from nodes.
Create a function in the controller that redirects to the expected route like so
redirectTo(uri:string){
this.router.navigateByUrl('/', {skipLocationChange: true}).then(()=>
this.router.navigate([uri]));
}
then use it like this
this.redirectTo('//place your uri here');
this function will redirect to a dummy route and quickly return to the destination route without the user realizing it.
This can now be done in Angular 5.1 using the onSameUrlNavigation
property of the Router config.
I have added a blog explaining how here but the gist of it is as follows
https://medium.com/engineering-on-the-incline/reloading-current-route-on-click-angular-5-1a1bfc740ab2
In your router config enable onSameUrlNavigation
option, setting it to 'reload'
. This causes the Router to fire an events cycle when you try to navigate to a route that is active already.
@ngModule({
imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: 'reload'})],
exports: [RouterModule],
})
In your route definitions, set runGuardsAndResolvers
to always
. This will tell the router to always kick off the guards and resolvers cycles, firing associated events.
export const routes: Routes = [
{
path: 'invites',
component: InviteComponent,
children: [
{
path: '',
loadChildren: './pages/invites/invites.module#InvitesModule',
},
],
canActivate: [AuthenticationGuard],
runGuardsAndResolvers: 'always',
}
]
Finally, in each component that you would like to enable reloading, you need to handle the events. This can be done by importing the router, binding onto the events and invoking an initialisation method that resets the state of your component and re-fetches data if required.
export class InviteComponent implements OnInit, OnDestroy {
navigationSubscription;
constructor(
// … your declarations here
private router: Router,
) {
// subscribe to the router events. Store the subscription so we can
// unsubscribe later.
this.navigationSubscription = this.router.events.subscribe((e: any) => {
// If it is a NavigationEnd event re-initalise the component
if (e instanceof NavigationEnd) {
this.initialiseInvites();
}
});
}
initialiseInvites() {
// Set default values and re-fetch any data you need.
}
ngOnDestroy() {
if (this.navigationSubscription) {
this.navigationSubscription.unsubscribe();
}
}
}
With all of these steps in place, you should have route reloading enabled.
EDIT
For newer versions of Angular (5.1+) use answer suggested by @Simon McClive
Old answer
I found this workaround on a GitHub feature request for Angular:
this._router.routeReuseStrategy.shouldReuseRoute = function(){
return false;
};
this._router.events.subscribe((evt) => {
if (evt instanceof NavigationEnd) {
this._router.navigated = false;
window.scrollTo(0, 0);
}
});
I tried adding this to my app.component.ts ngOnInit
function, and it sure worked. All further clicks on the same link now reloads the component
and data.
Link to original GitHub feature request
Credit goes to mihaicux2 on GitHub.
I tested this on version 4.0.0-rc.3
with import { Router, NavigationEnd } from '@angular/router';
I am using this one for Angular 11 project:
reloadCurrentRoute() {
const currentUrl = this.router.url;
this.router.navigateByUrl('/', {skipLocationChange: true}).then(() => {
this.router.navigate([currentUrl]);
});
}
PS: Tested and works on all versions above 7.
If your navigate() doesn't change the URL that already shown on the address bar of your browser, the router has nothing to do. It's not the router's job to refresh the data. If you want to refresh the data, create a service injected into the component and invoke the load function on the service. If the new data will be retrieved, it'll update the view via bindings.
This works for me like a charm
this.router.navigateByUrl('/', {skipLocationChange: true}).then(()=>
this.router.navigate([<route>]));
Little tricky: use same path with some dummy params. For example-
refresh(){
this.router.navigate(["/same/route/path?refresh=1"]);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With