How to reload the current route with the angular 2 router

AngularTypescript

Angular Problem Overview


I am using angular 2 with hashlocation strategy.

The component is loaded with that route:

"departments/:id/employees"

So far fine.

After I do a successful batch save of multiple edited table rows I want to reload the current route URL via:

this.router.navigate([`departments/${this.id}/employees`]);

But nothing happens, why?

Angular Solutions


Solution 1 - Angular

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.

Solution 2 - Angular

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.

Solution 3 - Angular

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';

Solution 4 - Angular

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.

Solution 5 - Angular

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.

Solution 6 - Angular

This works for me like a charm

this.router.navigateByUrl('/', {skipLocationChange: true}).then(()=>
this.router.navigate([<route>]));

Solution 7 - Angular

This is what I did with Angular 9. I'm not sure does this works in older versions.

You will need to call this when you need to reload.

 this.router.navigate([], {
    skipLocationChange: true,
    queryParamsHandling: 'merge' //== if you need to keep queryParams
  })

Router forRoot needs to have SameUrlNavigation set to 'reload'

 RouterModule.forRoot(appRoutes, {
  // ..
  onSameUrlNavigation: 'reload',
  // ..
})

And your every route needs to have runGuardsAndResolvers set to 'always'

{
    path: '',
    data: {},
    runGuardsAndResolvers: 'always'
},

Solution 8 - Angular

Little tricky: use same path with some dummy params. For example-

refresh(){
  this.router.navigate(["/same/route/path?refresh=1"]);
}

Solution 9 - Angular

Angular 2-4 route reload hack

For me, using this method inside a root component (component, which is present on any route) works:

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

  let currentUrl = this.router.url + '?';

  this.router.navigateByUrl(currentUrl)
    .then(() => {
      this.router.navigated = false;
      this.router.navigate([this.router.url]);
    });
  }

Solution 10 - Angular

On param change reload page won't happen. This is really good feature. There is no need to reload the page but we should change the value of the component. paramChange method will call on url change. So we can update the component data

/product/: id / details

import { ActivatedRoute, Params, Router } from@angular/router’;

export class ProductDetailsComponent implements OnInit {

constructor(private route: ActivatedRoute, private router: Router) {
    this.route.params.subscribe(params => {
        this.paramsChange(params.id);
    });
}

// Call this method on page change

ngOnInit() {

}

// Call this method on change of the param
paramsChange(id) {

}

Solution 11 - Angular

Found a quick and straight-forward solution that doesn't require to tinker with the inner workings of angular:

Basically: Just create an alternate route with the same destination module and just toggle between them:

const routes: Routes = [
  {
    path: 'gesuch',
    loadChildren: './sections/gesuch/gesuch.module#GesuchModule'
  },
  {
    path: 'gesuch-neu',
    loadChildren: './sections/gesuch/gesuch.module#GesuchModule'
  }
];

And here the toggeling menu:

<ul class="navigation">
    <li routerLink="/gesuch-neu" *ngIf="'gesuch' === getSection()">Gesuch</li>
    <li routerLink="/gesuch" *ngIf="'gesuch' !== getSection()">Gesuch</li>
</ul>

Hope it helps :)

Solution 12 - Angular

Solution:

Subscribe to URL params and initialize component there. No tricks, just "new URL --> new data", including first time loading.

For URL params (like /persons/:id):

constructor(protected activeRoute: ActivatedRoute, ...) {
    this.activeRoute.paramMap.subscribe(paramMap => {
        const id = paramMap.get('id');    // get param from dictonary
        this.load(id);                    // load your data
    });
}

For URL query params (like ?q=...&returnUrl=...) (usually not required):

    this.activeRoute.queryParamMap.subscribe(queryParamMap => {
        const returnUrl = queryParamMap.get('returnUrl');
        ...
    });

Problem's cause is:

When URL changes, Angular will reuse old component if possible to save computer's resources. Loading of data is your custom code, so that Angular can't do it for you.

Solution 13 - Angular

For me works hardcoding with

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

Solution 14 - Angular

A little bit hardcore but

this.router.onSameUrlNavigation = 'reload';
this.router.navigateByUrl(this.router.url).then(() => {

    this.router.onSameUrlNavigation = 'ignore';
                
});

Solution 15 - Angular

Import Router and ActivatedRoute from @angular/router

import { ActivatedRoute, Router } from '@angular/router';

Inject Router and ActivatedRoute (in case you need anything from the URL)

constructor(
    private router: Router,
    private route: ActivatedRoute,
) {}

Get any parameter if needed from URL.

const appointmentId = this.route.snapshot.paramMap.get('appointmentIdentifier');

Using a trick by navigating to a dummy or main url then to the actual url will refresh the component.

this.router.navigateByUrl('/appointments', { skipLocationChange: true }).then(() => {
    this.router.navigate([`appointment/${appointmentId}`])
});

In your case
const id= this.route.snapshot.paramMap.get('id');
this.router.navigateByUrl('/departments', { skipLocationChange: true }).then(() => {
    this.router.navigate([`departments/${id}/employees`]);
});

If you use a dummy route then you will see a title blink 'Not Found' if you have implemented a not found url in case does not match any url.

Solution 16 - Angular

implement OnInit and call ngOnInit() in method for route.navigate()

See an example :

export class Component implements OnInit {

  constructor() {   }

  refresh() {
    this.router.navigate(['same-route-here']);
    this.ngOnInit();   }

  ngOnInit () {

  }

Solution 17 - Angular

Solved a similar scenario by using a dummy component and route for reload, which actually does a redirect. This definitely doesn't cover all user scenarios but just worked for my scenario.

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { Http } from '@angular/http';

@Component({
  selector: 'reload',
  template: `
    <h1>Reloading...</h1>
  `,
})
export class ReloadComponent implements OnInit{
  constructor(private router: Router, private route: ActivatedRoute) {
  }

  ngOnInit() {
    const url = this.route.snapshot.pathFromRoot.pop().url.map(u => u.path).join('/');
    this.router.navigateByUrl(url);
  }
}

The routing is wired to catch all urls using a wildcard:

import { RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
import { LoginViewComponent } from './views/login/login.component';
import { HomeViewComponent } from './views/home/home.component';
import { ReloadComponent } from './views/reload/reload.component';

@NgModule({
  declarations: [ 
    LoginViewComponent, HomeViewComponent, ReloadComponent
  ],
  imports: [
    RouterModule.forRoot([
      { path: 'login', component: LoginViewComponent },
      { path: 'home', component: HomeViewComponent },
      { 
        path: 'reload',
        children: [{
          path: '**',
          component: ReloadComponent 
        }]
      },
      { path: '**', redirectTo: 'login'}
    ])
  ],
  exports: [
    RouterModule,
  ],
  providers: [],

})
export class AppRoutingModule {}

To use this, we just need to add reload to the url where we want to go:

  this.router.navigateByUrl('reload/some/route/again/fresh', {skipLocationChange: true})

Solution 18 - Angular

A solution is to pass a dummy parameter (i.e. the time in seconds), in this way the link is always reloaded:

this.router.navigate(["/url", {myRealData: RealData, dummyData: (new Date).getTime()}])

Solution 19 - Angular

There are different approaches to refresh the current route

Change router behaviour (Since Angular 5.1) Set the routers onSameUrlNavigation to 'reload'. This will emit the router events on same URL Navigation.

  • You can then handle them by subscribing to a route
  • You can use it with the combination of runGuardsAndResolvers to rerun resolvers

Leave the router untouched

  • Pass a refresh queryParam with the current timestamp in the URL and subscribe to queryParams in your routed component.
  • Use the activate Event of the router-outlet to get a hold of the routed component.

I have written a more detailed explanation under https://medium.com/@kevinkreuzer/refresh-current-route-in-angular-512a19d58f6e

Hope this helps.

Solution 20 - Angular

I am using setTimeout and navigationByUrl to solve this issue... And it is working fine for me.

It is redirected to other URL and instead comes again in the current URL...

 setTimeout(() => {
     this.router.navigateByUrl('/dashboard', {skipLocationChange: false}).then(() =>
           this.router.navigate([route]));
     }, 500)

Solution 21 - Angular

Very frustrating that Angular still doesn't seem to include a good solution for this. I have raised a github issue here: https://github.com/angular/angular/issues/31843

In the meantime, this is my workaround. It builds on some of the other solutions suggested above, but I think it's a little more robust. It involves wrapping the Router service in a "ReloadRouter", which takes care of the reload functionality and also adds a RELOAD_PLACEHOLDER to the core router configuration. This is used for the interim navigation and avoids triggering any other routes (or guards).

Note: Only use the ReloadRouter in those cases when you want the reload functionality. Use the normal Router otherwise.

import { Injectable } from '@angular/core';
import { NavigationExtras, Router } from '@angular/router';

@Injectable({
  providedIn: 'root'
})
export class ReloadRouter {
  constructor(public readonly router: Router) {
    router.config.unshift({ path: 'RELOAD_PLACEHOLDER' });
  }

  public navigate(commands: any[], extras?: NavigationExtras): Promise<boolean> {
    return this.router
      .navigateByUrl('/RELOAD_PLACEHOLDER', {skipLocationChange: true})
      .then(() => this.router.navigate(commands, extras));
  }
}

Solution 22 - Angular

Write a function—e.g., reloadCurrentPage. As window is a global object which can be reused directly in Angular components, window.location.reload() reloads the currently active page.

function reloadCurrentPage() {
    window.location.reload();
}

Solution 23 - Angular

In my case:

const navigationExtras: NavigationExtras = {
    queryParams: { 'param': val }
};

this.router.navigate([], navigationExtras);

work correct

Solution 24 - Angular

Suppose that the component's route you want to refresh is view, then use this:

this.router.routeReuseStrategy.shouldReuseRoute = function (future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot) {
  if (future.url.toString() === 'view' && curr.url.toString() === future.url.toString()) {
    return false;
  }
  return (future.routeConfig === curr.routeConfig);
}; 

you can add a debugger inside the method to know what is the exact route will come after navigate to "departments/:id/employees".

Solution 25 - Angular

using 'timestamp' is a cheap and amazing way.

this.router.navigate([], {
    relativeTo: this.route,
    queryParams: {
        ...this.route.snapshot.queryParams,
        // replace 't' with any others not to conflict with exsiting
        // '2^11' prevents reloading in about 2 seconds
        t: Date.now() >> 11, 
        skipLocationChange: true,
    },
});

Solution 26 - Angular

subscribe to route parameter changes

	// parent param listener ie: "/:id"
	this.route.params.subscribe(params => {
		// do something on parent param change
		let parent_id = params['id']; // set slug
	});

	// child param listener ie: "/:id/:id"
	this.route.firstChild.params.subscribe(params => {
		// do something on child param change
		let child_id = params['id'];
	});

Solution 27 - Angular

If you are changing route via Router Link Follow this:

  constructor(public routerNavigate: Router){

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

          this.router.events.subscribe((evt) => {

            if (evt instanceof NavigationEnd) {

                this.router.navigated = false;
             }
          })
      }

Solution 28 - Angular

I believe this has been solved (natively) in Angular 6+; check

But this works for an entire route (includes all children routes as well)

If you want to target a single component, here's how: Use a query param that changes, so you can navigate as many times as you want.

At the point of navigation (class)

   this.router.navigate(['/route'], {
        queryParams: { 'refresh': Date.now() }
    });

In Component that you want to "refresh/reload"

// . . . Component Class Body

  $_route$: Subscription;
  constructor (private _route: ActivatedRoute) {}

  ngOnInit() {
    this.$_route$ = this._route.queryParams.subscribe(params => {
      if (params['refresh']) {
         // Do Something
         // Could be calling this.ngOnInit() PS: I Strongly advise against this
      }

    });
  }
 
  ngOnDestroy() {
    // Always unsubscribe to prevent memory leak and unexpected behavior
    this.$_route$.unsubscribe();
  }

// . . . End of Component Class Body

Solution 29 - Angular

Decides when the route should be stored return false to

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

and set the navigated value of router to false, that show that this route never routed

this.mySubscription = this.router.events.subscribe(event => {
    if (event instanceof NavigationEnd) {
        this.router.navigated = false;
    }
});

Solution 30 - Angular

I have tried a few fixes and none of them works. My version is simple: add a new unused parameter into query parameters

            if (force) {
                let key = 'time';

                while (key in filter) {
                    key = '_' + key;
                }

                filter[key] = Date.now();
            }

            this.router.navigate(['.', { filter: JSON.stringify(filter) }]);

Solution 31 - Angular

This below code will work:

logoFn(url: any) {

    this.router.routeReuseStrategy.shouldReuseRoute = function () {
        return false;
    };
    this.router.navigate(['']); or
    this.router.navigate([url]);

}

Solution 32 - Angular

This worked for me:

let url = `departments/${this.id}/employees`;

this.router.navigated = false;
this.router.navigateByUrl(url);

Solution 33 - Angular

reload current route in angular 2 very helpful link to reload current route in angualr 2 or 4

in this define two technique to do this

  1. with dummy query params
  2. with dummy route

for more see above link

Solution 34 - Angular

Try this

> window.open('dashboard', '_self');

its old method but works on all angular version, where it redirect on route and refresh the page.

Solution 35 - Angular

Another option is to use plain js but the page will actually refresh.

window.location.reload(true)

Solution 36 - Angular

just use native javascript reload method:

reloadPage() {
    window.location.reload();
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPascalView Question on Stackoverflow
Solution 1 - Angulartheo sharksonView Answer on Stackoverflow
Solution 2 - AngularSimon McCliveView Answer on Stackoverflow
Solution 3 - AngularArg0nView Answer on Stackoverflow
Solution 4 - AngularAndrisView Answer on Stackoverflow
Solution 5 - AngularYakov FainView Answer on Stackoverflow
Solution 6 - AngularNitin KamateView Answer on Stackoverflow
Solution 7 - AngularWladaView Answer on Stackoverflow
Solution 8 - AngularnewariView Answer on Stackoverflow
Solution 9 - AngularindreedView Answer on Stackoverflow
Solution 10 - AngularkarthiView Answer on Stackoverflow
Solution 11 - AngularCarli BeeliView Answer on Stackoverflow
Solution 12 - AngularEvgeny NozdrevView Answer on Stackoverflow
Solution 13 - AngularVladView Answer on Stackoverflow
Solution 14 - AngularDzmitry VasilevskyView Answer on Stackoverflow
Solution 15 - AngularAamer ShahzadView Answer on Stackoverflow
Solution 16 - AngularEvandro MendesView Answer on Stackoverflow
Solution 17 - AngularsabithpockerView Answer on Stackoverflow
Solution 18 - AngularlosciurView Answer on Stackoverflow
Solution 19 - AngularTrafalgarView Answer on Stackoverflow
Solution 20 - Angularajay hariyalView Answer on Stackoverflow
Solution 21 - AngularDan KingView Answer on Stackoverflow
Solution 22 - AngularrajquestView Answer on Stackoverflow
Solution 23 - AngularAnton ZimmView Answer on Stackoverflow
Solution 24 - AngularEbraheem AlrabeeaView Answer on Stackoverflow
Solution 25 - AngularXiaodi HU View Answer on Stackoverflow
Solution 26 - AngularOmarView Answer on Stackoverflow
Solution 27 - AngularOmkar JoshiView Answer on Stackoverflow
Solution 28 - Angularmbao01View Answer on Stackoverflow
Solution 29 - Angularmohit sharmaView Answer on Stackoverflow
Solution 30 - Angulartom10271View Answer on Stackoverflow
Solution 31 - AngularMartin JesuView Answer on Stackoverflow
Solution 32 - AngularmaggicView Answer on Stackoverflow
Solution 33 - AngularRituraj ratanView Answer on Stackoverflow
Solution 34 - AngularKavi JoshiView Answer on Stackoverflow
Solution 35 - AngularAusten StoneView Answer on Stackoverflow
Solution 36 - AngularAugusto ClaroView Answer on Stackoverflow