How to reload the current route with the angular 2 router
Asked Answered
C

37

274

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?

Crwth answered 5/12, 2016 at 20:48 Comment(4)
Take a look at this answer to a similar question: https://mcmap.net/q/110460/-can-39-t-reload-refresh-active-routeCarioca
tech-blog.maddyzone.com/angularjs/javascript/… very helpfulEmbolism
Solution: subscribe to query params and load data from there. No tricks, just "URL changed --> data reloaded" (including first time). More: https://mcmap.net/q/108234/-how-to-reload-the-current-route-with-the-angular-2-routerBigler
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.Bigler
R
56

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.

Roselleroselyn answered 5/12, 2016 at 21:1 Comment(10)
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...Crwth
I don't agree what if you want to rerun the guards, say if someone logs out?Trump
@Trump I was thinking that maybe you could just rerun the guards... if they have redirects built in, then that might do the trick.Insincere
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.Roselleroselyn
@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.Wish
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.Titanium
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.Bite
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.Suppression
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!Impetigo
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.Knucklebone
O
301

Create a function in the controller that redirects to the expected route like this:

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

Then you 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.

Otti answered 27/3, 2018 at 9:52 Comment(10)
it works like a charm when i used '/' instead of '/DummyComponent'Cadaverous
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.Luzern
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.Practicable
nice solution even with: this.router.navigateByUrl(parentroute).then(()=> this.router.navigateByUrl(childroute) );Shook
Nice answer, please avoid the word controller.Averil
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 lagCystectomy
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.Clang
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.Ser
@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: meta.#326595Kostman
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.Henninger
S
203

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.

Sayres answered 16/1, 2018 at 11:18 Comment(8)
Is there a way to reload the component instead of calling an init function,Neidaneidhardt
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?Sayres
I have figured out a solution for my problem,Thank you for your response and the blog it was useful.Neidaneidhardt
How to do it in Angular 4 other than window reload.Forecastle
Works great for my Angular5 app! Unsubscribing in ngOnDestroy() is kinda important - interesting when you don't do it :-)Pestana
How do you do this in a child module?Marenmarena
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?Hapsburg
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 anyoneEnteric
G
107

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.

Gourmandise answered 26/9, 2019 at 10:29 Comment(6)
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.Firstfoot
Best answer for my purpose +1Router
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.Riesman
Doesn't work for me in angular13Hebrides
This fix working fine with Angular ^14.0.5.Description
Kudos work for me like a charmChamorro
B
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';

Bulbiferous answered 17/8, 2017 at 14:1 Comment(10)
Just tried this in Angular 4.4.x and this completely works. Thanks!Dowden
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...)Crib
This is a very bad idea — your ActivatedRoute now will always be the same.Wales
Be careful before you implement this, this make fail your routes with guard CanActivate: []Modification
@Bulbiferous 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(localhost:4200/client/Alte3SkwvtKO0FkweU1J/edit) add in url after that I want to refresh before going to update it occour error.Mielke
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.Philipphilipa
@AnandTyagi Try SimonMcClives solution if you're on Angular 5.1+. Maybe that works better for you.Bulbiferous
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?Chinfest
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.Luzern
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.Sanderlin
I
58

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'
},
Impresa answered 29/3, 2020 at 3:20 Comment(4)
This is the correct answer. "onSameUrlNavigation" works since Angular 5. Please upvote to move it to the topPouncey
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.Firstfoot
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 @ImpresaChemise
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.Parke
R
56

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.

Roselleroselyn answered 5/12, 2016 at 21:1 Comment(10)
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...Crwth
I don't agree what if you want to rerun the guards, say if someone logs out?Trump
@Trump I was thinking that maybe you could just rerun the guards... if they have redirects built in, then that might do the trick.Insincere
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.Roselleroselyn
@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.Wish
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.Titanium
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.Bite
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.Suppression
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!Impetigo
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.Knucklebone
N
39

This works for me like a charm

this.router.navigateByUrl('/', {skipLocationChange: true}).then(()=>
this.router.navigate([<route>]));
Nonce answered 26/10, 2018 at 7:49 Comment(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.Cosmopolite
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 ?Legrand
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.Nonce
S
32

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

refresh(){
  this.router.navigate(["/same/route/path?refresh=1"]);
}
Superstar answered 12/3, 2017 at 22:27 Comment(3)
Now: this.router.navigate(['/pocetna'], { queryParams: { 'refresh': 1 } }); and route.queryParams.subscribe(val => myRefreshMethod()) where route: ActivatedRoute is injected in refreshed component... Hope it helpsMachicolation
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.)Audile
A little ugly maybe.Ehr
B
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]);
    });
  }
Biblicist answered 22/1, 2018 at 11:1 Comment(1)
Be careful with this approach, this will globally affect router behavior (parent route will always reload when navigating between child routes).Transferor
S
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) {

}
Shafting answered 11/8, 2018 at 6:41 Comment(0)
N
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 :)

Nasho answered 14/9, 2017 at 12:49 Comment(1)
What if the alternate route has parameter and you want to re-load when parameter changes?Jarlath
B
6

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.

Bigler answered 23/7, 2021 at 18:15 Comment(1)
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.Bigler
E
5

For me works hardcoding with

this.router.routeReuseStrategy.shouldReuseRoute = function() {
    return false;
    // or
    return true;
};
Existent answered 7/1, 2018 at 9:58 Comment(2)
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.Arithmetician
If you must use this use Ebraheem Alrabee' solution and only apply it to a single route.Arithmetician
G
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.

God answered 13/12, 2019 at 11:31 Comment(1)
who art thou sir who are so wise in ways of AngularAssignable
R
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 () {

  }
Redfin answered 14/3, 2018 at 22:22 Comment(0)
F
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()}])
Fathomless answered 30/10, 2018 at 13:47 Comment(1)
Funny trick indeed ;)Mara
B
3

A little bit hardcore but

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

    this.router.onSameUrlNavigation = 'ignore';

});
Blotchy answered 1/11, 2018 at 16:27 Comment(0)
R
3

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();
}
Rita answered 2/2, 2022 at 17:38 Comment(0)
E
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})
Eliza answered 14/5, 2018 at 10:51 Comment(0)
S
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.

Shrieval answered 27/11, 2018 at 7:36 Comment(0)
O
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)
Orvilleorwell answered 30/4, 2019 at 7:9 Comment(0)
T
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));
  }
}
Titanium answered 25/7, 2019 at 16:13 Comment(0)
E
1

In my case:

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

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

work correct

Epicontinental answered 26/12, 2017 at 14:7 Comment(0)
N
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".

refer to this answer for more detailed solution.

Neidaneidhardt answered 19/3, 2018 at 19:45 Comment(0)
I
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,
    },
});
Illuminometer answered 3/3, 2022 at 2:44 Comment(1)
Doesn't work for me in angular13Hebrides
C
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'];
    });
Chinfest answered 26/4, 2018 at 16:55 Comment(0)
M
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;
             }
          })
      }
Malfeasance answered 6/6, 2019 at 6:9 Comment(0)
Z
0

This below code will work:

logoFn(url: any) {

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

}
Zackzackariah answered 11/6, 2019 at 5:6 Comment(0)
R
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
Roller answered 26/6, 2019 at 23:46 Comment(1)
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.Marquez
T
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;
    }
});
Transmundane answered 4/4, 2020 at 11:24 Comment(0)
O
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) }]);
Orlosky answered 6/4, 2020 at 3:14 Comment(0)
O
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])
     }
   }
Objectify answered 19/4, 2023 at 7:42 Comment(1)
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?Heliopolis
S
-2

This worked for me:

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

this.router.navigated = false;
this.router.navigateByUrl(url);
Souffle answered 30/8, 2017 at 8:18 Comment(1)
Just tried this in the latest version of Angular 4 and it no longer works.Endless
E
-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

Embolism answered 8/2, 2018 at 6:26 Comment(0)
S
-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.

Sundsvall answered 5/3, 2018 at 8:47 Comment(0)
U
-4

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

window.location.reload(true)
Ultann answered 9/8, 2021 at 12:54 Comment(1)
Reloading page this way changes meaning of SPA.Verile
R
-35

just use native javascript reload method:

reloadPage() {
    window.location.reload();
}
Ronironica answered 20/2, 2017 at 16:55 Comment(4)
This will reload the entire application, causing you to lose anything stored in the session, like user information, scope data, etcProleg
Not in session, but in memory. Session data should be stored with sessionStorage API.Fatling
Had to use this one for my login page navigation...angular app was initialized without state fetch from server (because not logged)...Cacuminal
Sorry for all the people downvoting without thinking. Sometimes you specifically need to restart your application with the same route. That is what you do then. Perfectly viable solution.Ierna

© 2022 - 2024 — McMap. All rights reserved.