262

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?

Mario Petrovic
  • 7,500
  • 14
  • 42
  • 62
Pascal
  • 12,265
  • 25
  • 103
  • 195
  • Take a look at this answer to a similar question: https://stackoverflow.com/a/44580036/550975 – Serj Sagan Jun 16 '17 at 02:55
  • http://tech-blog.maddyzone.com/angularjs/javascript/how-reload-current-route-angular2 very helpful – Rituraj ratan Feb 08 '18 at 06:23
  • **Solution:** subscribe to query params and load data from there. No tricks, just "URL changed --> data reloaded" (including first time). **More:** https://stackoverflow.com/a/68503542/7573844 – Evgeny Nozdrev Jul 23 '21 at 18:17
  • 1
    **Cause:** Angular reuse component if possible to save computer's resources. Loading of data is your *custom* logic, Angular can't do it for you. – Evgeny Nozdrev Jul 23 '21 at 18:42

37 Answers37

283

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.

Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
theo sharkson
  • 2,847
  • 2
  • 9
  • 5
  • 21
    it works like a charm when i used `'/'` instead of `'/DummyComponent'` – suhailvs Sep 06 '18 at 06:43
  • This is a very bad idea, because as I just discovered after having used it for a while, it pollutes the browser history with 'page not found' entries. It seems that either `skipLocationChange` is not working as expected, or there is a bug. I tried setting `replaceUrl` to false too, but still no luck. – AsGoodAsItGets Mar 13 '19 at 15:07
  • 4
    Works fine in Angular 7, without problems in the browser history. I opted to use this solution due to being targeted to a specific component. It seems to me that reloading the same page is generally an abnormal case, so making the entire application follow a specific paradigm seems like overkill. This is small and easier to implement than other solutions. – J E Carter II Apr 16 '19 at 14:44
  • nice solution even with: this.router.navigateByUrl(parentroute).then(()=> this.router.navigateByUrl(childroute) ); – selma Mar 22 '20 at 18:01
  • Nice answer, please avoid the word controller. – Dejazmach Mar 31 '20 at 17:20
  • 5
    Okay it works but... it will reload your HomeComponent (or whatever you have on the route "/"), will go throught the full lifecycle of ngOnInit/ngOnDestroy for nothing. Better to have a specific route with some dummy and lightweight component or you will notice the lag – petronius Apr 16 '20 at 09:22
  • 1
    This does not address if you want to refresh the '/' page. You'd need to navigate to another page in that instance (I ran into this issue). Someone suggested creating a dummy page, I think that's a good idea if you want this solution to work cleanly. In my case, I opted for the top solution, but it appeared that this also was a quick and dirty solution that would work. – Travis L. Riffle Sep 04 '20 at 00:21
  • 2
    This is the best answer. I ended up making a /dummy component and added a route for it, and then everything worked perfectly on Angular 10. – TomKraljevic Oct 14 '20 at 21:16
  • @DorinBaba even though it has over 3x the votes of the "top" answer (at the time of writing), the top answer was accepted by the question asker. See also: https://meta.stackoverflow.com/questions/326095/please-unpin-the-accepted-answer-from-the-top – Ollie Jul 29 '21 at 02:27
  • I had to use '*' as my away route cuz when i was already at '/scenario' page and tried to navigate away with '/' and back to '/scenario', it did not work (i-e reload the component) because '/' got matched with the empty route mapping `{ path: '', redirectTo: 'scenario', pathMatch: 'full' }` i had in my routes config. – oomer Jul 21 '22 at 21:02
197

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.

Nate Anderson
  • 18,334
  • 18
  • 100
  • 135
Simon McClive
  • 2,516
  • 3
  • 17
  • 13
  • 2
    Is there a way to reload the component instead of calling an `init` function, – Ebraheem Alrabeea Feb 06 '18 at 18:34
  • I don't think so... unless you navigate away from the route and back again. An init function isn't the end of the world, you can control the initialisation to the point that it has the same effect as reloading the component. Is there any particular reason you want to do a full reload without `init`? – Simon McClive Feb 07 '18 at 14:15
  • I have figured out a solution for my problem,Thank you for your response and the blog it was useful. – Ebraheem Alrabeea Feb 10 '18 at 18:29
  • How to do it in Angular 4 other than window reload. – Vishakha Apr 04 '18 at 09:35
  • Works great for my Angular5 app! Unsubscribing in ngOnDestroy() is kinda important - interesting when you don't do it :-) – BobC Feb 07 '19 at 17:15
  • How do you do this in a child module? – Jonathan Mar 26 '20 at 02:10
  • 1
    What if I need this behavior in all pages? Is there a way to develop a standard behavior so that all pages are reloading (calling ionWillEnter) when navigating same url without having to handle events on each page component? – sabrina May 20 '20 at 08:53
  • This approach worked for me but it wasn't updating the @input variable (I'm navigating between details pages) so I grabbed the :id from the URL instead. I'm sure there's a cleaner way to do this but incase it helps anyone – Chris A Aug 23 '23 at 09:34
103

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.

Andris
  • 3,895
  • 2
  • 24
  • 27
  • 4
    I thought I'd chime in on my experience with this solution. For me, it seems to reload the entire component associated with the route. In my situation a regular router.navigate with different routing params will keep the component loaded and just load the new changes from ngOnInit (based on route params). Your solution doesn't seem to do this, it seems to actually reload the entire component and then make it's changes in the ngOnInit based on route params. Anyhow, it's a minor inconvenience for me in my situation and your solution works for my needs. – Evan Sevy Apr 19 '20 at 01:08
  • Best answer for my purpose +1 – Paulquappe Apr 13 '21 at 20:32
  • This doesn't seem to work for me. My situation is I want to reload on leaving an app state, so I have this wrapped in an `if` to check the previous state of the app. If it's true we were in the "other" state but are no longer there, the state flag is reset and this code runs, but nothing happens. I've used `window.location.reload();`, but that seems to be a much more brute force approach. None of the other suggestions in this thread have worked either. – PaulBunion Nov 04 '21 at 14:43
  • Doesn't work for me in angular13 – mirik Sep 08 '22 at 10:15
  • This fix working fine with Angular ^14.0.5. – Gopi Feb 15 '23 at 15:56
  • Kudos work for me like a charm – Developer Jul 24 '23 at 09:52
82

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

Arg0n
  • 8,283
  • 2
  • 21
  • 38
  • 1
    Just tried this in Angular 4.4.x and this completely works. Thanks! – Mindsect Team Oct 21 '17 at 04:39
  • 1
    This was working great for me, until I implemented Material's nav-tab-bar for navigating through the children routes of each parent route in my app. Once the user hits the page that runs this code, the animated ink bar will disappear. (Why? I don't have enough time or space to explain...) – andreisrob Dec 22 '17 at 20:12
  • 4
    This is a very bad idea — your ActivatedRoute now will always be the same. – artuska May 22 '18 at 12:57
  • Be careful before you implement this, this make fail your routes with guard `CanActivate: []` – Sibeesh Venu Jul 12 '18 at 07:43
  • @Arg0n I added the above code in app.component.ts but it didn't work for me. The issue I am facing is when is get single user id for edit this id(http://localhost:4200/client/Alte3SkwvtKO0FkweU1J/edit) add in url after that I want to refresh before going to update it occour error. – Naeem Jul 22 '18 at 11:17
  • This sure works but I really wish there was another to invoke the subscribe method of activated route. This solution works with kind of a glitch and you can see the visual flickering. – आनंद Sep 20 '18 at 19:46
  • 2
    @AnandTyagi Try SimonMcClives solution if you're on Angular 5.1+. Maybe that works better for you. – Arg0n Sep 21 '18 at 06:58
  • this works for me but after installing `shouldReuseRoute()` then `this.route.snapshot.firstChild.data` is `null` but it was not null before... Any idea how to reach route data after installing this method? – Omar Oct 10 '18 at 15:45
  • Returning false for all `shouldReuseRoute` is a very bad idea, as I just discovered myself. Among other things, it breaks a solution I found by Todd Motto to dynamically change the page title based on route data. – AsGoodAsItGets Mar 13 '19 at 15:23
  • 3
    Very bad idea... Because once it applied routeReuseStrategy.shouldReuseRoute = false, then it will load every component of component hierarchy. So it mean your every parent and child component starts reload on any url changes. So then there is no meaning of using this framework. – PSabuwala Jun 23 '19 at 09:55
57

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.

Yakov Fain
  • 11,972
  • 5
  • 33
  • 38
  • 2
    Now you say it I must agree BUT... the angularjs ui router had a reload option thus reloading a route is opiniated ;-) But yeah I could just do a reload data thx for that tip which is actually obvious... – Pascal Dec 05 '16 at 21:03
  • 120
    I don't agree what if you want to rerun the guards, say if someone logs out? – Jackie Feb 08 '17 at 19:39
  • 1
    @Jackie I was thinking that maybe you could just rerun the guards... if they have redirects built in, then that might do the trick. – OldTimeGuitarGuy Sep 29 '17 at 02:12
  • 1
    I the route already opened, there's no need in guards like CanLoad. The data for resolver should be provided by a service (initially injected into the resolver). Nothing stops you from explicitly invoking the method on the service that reloads the data. – Yakov Fain Jan 31 '18 at 18:37
  • 21
    @YakovFain sorry, but this is false. This means you now have two sources of truth for the route behavior - one happens during the guard, the other happens in the component. Not only are you now potentially duplicating logic, you are bucking against a more natural data flow: 1. make changes to API, 2. refresh the route to fetch the new state of data from the API, making the API the source of truth. There is simply not reason NOT to give users the ability to manually re-trigger a route so that the natural flow of data can happen again. – AgmLauncher Nov 07 '18 at 17:44
  • 5
    I don't think this is a good answer. The router should be the source of truth for your data. If you have to reload it via a separate service, then the router no longer knows about the latest version and your components can no longer rely on your router as the source of truth. – Dan King Jul 25 '19 at 10:55
  • 2
    There's also problem with this solution if you have multiple routes to the same component. Changing a route when it ends up going to the same component doesn't reload. – Rick Strahl Nov 09 '19 at 20:08
  • I don't think this answer is helpful in any way. Obviously you could reload the data manually. Navigating to a state doesn't just affect the URL, it affects the application state. Why shouldn't someone be able to reset to the initial state of the current component? Virtually every other router supports this behavior. – Joel Kornbluh Jan 06 '20 at 20:37
  • 1
    And also sometimes there are bugs that require you to refresh a page! Like if you return false from a `CanLoad` handler when trying to load a lazy route as your **first** navigation and then try to redirect to `/` to just go back to the homepage - the router thinks you're already there! – Simon_Weaver Feb 19 '20 at 00:36
  • This makes no sense. The router should give an easy option that imitates "window.location = ...." without reloading the whole application. What this angular's team yet another stubborness does is make the developer just reload the whole window instead of wasting so much time on such a trivial matter. – Cesar Mar 16 '23 at 15:03
55

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

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'
},
Wlada
  • 1,052
  • 14
  • 25
  • 9
    This is the correct answer. "onSameUrlNavigation" works since Angular 5. Please upvote to move it to the top – Yaroslav Yakovlev Apr 06 '20 at 00:22
  • This didn't work for me. Andris's below did. Although Andris's reloading isn't as 'clean' as an actual regular route navigation. It doesn't seem to reload the entire page, but it does seem to reload the entire component associated with the route. I just needed child components to reload based on route parameters, not the entire component associated with the route. Anyhow, it works well enough. Just thought I'd chime in on my experience. – Evan Sevy Apr 19 '20 at 01:02
  • 5
    My issue was solved by the last bit of code. Setting runGuardsAndResolvers: 'always' forced the app to use the guard therefore repeating the call to the API that existed there. Thanks for that @Wlada – Travel and code enthousiast Oct 01 '20 at 06:58
  • I also needed to add a custom RouteReuseStrategy which has shouldReuse = () => false, together with the answer - and that fixed my scenario and recreates the component. – mar10 Jan 19 '23 at 11:28
39

This works for me like a charm

this.router.navigateByUrl('/', {skipLocationChange: true}).then(()=>
this.router.navigate([<route>]));
Nitin Kamate
  • 2,545
  • 1
  • 18
  • 13
  • 3
    This is the simplest answer. I would mark this as the accepted answer if I could. Contrary to the accepted answer, there may be situations where you need to reload every single component used on a page and to have to individually reload each one, which may be at different routes, would be overkill even via a service. – Andrew Howard Mar 18 '19 at 16:51
  • Doesn't seem to work for me. I was expecting that this would re-trigger the ngOnInit function again. Apparently it doesn't.. Or m i missing smthing ? – Saurabh Tiwari Dec 09 '20 at 07:06
  • ngOnInit function will not be triggered if you are in the same route already. If you need that to be called, you can call it manually as a third line to the code mentioned above. – Nitin Kamate Dec 14 '20 at 08:24
32

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

refresh(){
  this.router.navigate(["/same/route/path?refresh=1"]);
}
newari
  • 465
  • 4
  • 5
  • 12
    Now: `this.router.navigate(['/pocetna'], { queryParams: { 'refresh': 1 } });` and `route.queryParams.subscribe(val => myRefreshMethod())` where `route: ActivatedRoute` is injected in refreshed component... Hope it helps – insan-e Aug 02 '17 at 14:25
  • 8
    Presently in Angular 7 this doesn't appear to work any more. Can anyone confirm, or am I doing something wrong? (I tried insan-e's slight variation too.) – pbristow Mar 26 '19 at 13:35
  • 3
    A little ugly maybe. – David Sep 22 '19 at 17:35
19

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]);
    });
  }
indreed
  • 1,235
  • 13
  • 11
  • Be careful with this approach, this will globally affect router behavior (parent route will always reload when navigating between child routes). – seidme Apr 30 '20 at 10:15
12

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) {

}
karthi
  • 167
  • 2
  • 5
6

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 :)

Carli Beeli
  • 790
  • 1
  • 11
  • 26
  • What if the alternate route has parameter and you want to re-load when parameter changes? – Mukus Apr 19 '19 at 07:13
5

For me works hardcoding with

this.router.routeReuseStrategy.shouldReuseRoute = function() {
    return false;
    // or
    return true;
};
Vlad
  • 7,997
  • 3
  • 56
  • 43
  • 5
    Not recommended! People keep re-posting this solution in different ways throughout this SO. Yes it may fix your immediate issue but you are going to forget later that you implemented this and you'll be spending hours trying to find out why your app is experiencing weird behavior. – Post Impatica Sep 27 '19 at 13:53
  • If you must use this use Ebraheem Alrabee' solution and only apply it to a single route. – Post Impatica Sep 27 '19 at 14:04
5

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.

Evgeny Nozdrev
  • 1,530
  • 12
  • 15
  • Note that `id` is read as string since whole URL is a string. Use `new Guid(id)` to convert a string to Guid. Or even use `new Guid(id || Guid.empty)` to has zeros-Guid if `id` not present in URL. – Evgeny Nozdrev Jul 23 '21 at 18:28
4

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.

Aamer Shahzad
  • 2,617
  • 1
  • 27
  • 25
3

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 () {

  }
3

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()}])
losciur
  • 63
  • 6
3

A little bit hardcore but

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

    this.router.onSameUrlNavigation = 'ignore';

});
Dzmitry Vasilevsky
  • 1,295
  • 2
  • 14
  • 25
2

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})
sabithpocker
  • 15,274
  • 1
  • 42
  • 75
2

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.

Trafalgar
  • 361
  • 1
  • 4
  • 14
2

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)
Beyazid
  • 1,795
  • 1
  • 15
  • 28
ajay hariyal
  • 243
  • 2
  • 9
2

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));
  }
}
Dan King
  • 3,412
  • 5
  • 24
  • 23
2

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();
}
Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
rajquest
  • 535
  • 1
  • 5
  • 10
1

In my case:

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

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

work correct

Anton Zimm
  • 420
  • 4
  • 14
1

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".

Ebraheem Alrabeea
  • 2,130
  • 3
  • 23
  • 42
1

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,
    },
});
0

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'];
    });
Omar
  • 2,726
  • 2
  • 32
  • 65
0

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;
             }
          })
      }
0

This below code will work:

logoFn(url: any) {

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

}
Syed mohamed aladeen
  • 6,507
  • 4
  • 32
  • 59
0

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
mbao01
  • 160
  • 3
  • 6
  • Interestingly, this approach will only work _once_ - it seems there's a bug in Angular where the `queryParamsMap` subject only gets updated the first time, but not on any subsequent updates. – Andrew Gray Oct 20 '20 at 21:20
0

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;
    }
});
Basel Issmail
  • 3,847
  • 7
  • 20
  • 36
Mohit Sharma
  • 622
  • 6
  • 11
0

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) }]);
tom10271
  • 4,222
  • 5
  • 33
  • 62
0

In file html:

<a class="clicable" (click)="menu('/proyects')">Proyects</a>

in file ts:

    menu(uri:string){
     if(this.router.url == uri){
        window.location.reload();
     }else{
        this.router.navigate([uri])
     }
   }
  • There is additional code which is not present in the question, and it's not clear to me why it's there. Could you please explain why you added the additional code? – JSON Derulo Apr 22 '23 at 09:39
-2

This worked for me:

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

this.router.navigated = false;
this.router.navigateByUrl(url);
maggic
  • 19
  • 1
  • 4
-2

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

Rituraj ratan
  • 10,260
  • 8
  • 34
  • 55
-3

Try this

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

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

Kavi Joshi
  • 173
  • 2
  • 5
-4

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

window.location.reload(true)
Austen Stone
  • 948
  • 1
  • 10
  • 21
-36

just use native javascript reload method:

reloadPage() {
    window.location.reload();
}
  • This will reload the entire application, causing you to lose anything stored in the session, like user information, scope data, etc – AJ Zane Mar 07 '17 at 20:13
  • 5
    Not in session, but in memory. Session data should be stored with sessionStorage API. – Petr Odut Jul 14 '17 at 10:32
  • Had to use this one for my login page navigation...angular app was initialized without state fetch from server (because not logged)... – Camille Jan 14 '21 at 13:55