'How to reload current page?
I have a page for editing user, it has some children components inside. Each children components can change or doing some effect to its parent component.
So instead of emitting the changes to parent and updating some fields, I did a "reload" of the current page with
private route: ActivatedRoute;
reload(){
this.router.navigate(["/admin/user/edit/"+this.user.id]);
}
Basically, it redirects to the current page. For example, the current page is http://web.info/admin/user/edit/9 it will be redirected to this page with the hope all the data inside that page reloaded with the newest data.
but it seems the angular won't redirect/reload the same page with the router.navigate
How I should reload a current page?
Edit:
Here is the reason why I need to reload the page instead of manually updating the data on the current page. I need to do updates on Other Component, when I did the update it will add something to History Component. I need to refresh the User Component and History Component together since both components affected by the changes in Other Component.
Solution 1:[1]
A little bit tricky to do something so simple but had no luck trying to reload and recreate the entire parent & child components with current solution.
Angular Router now provides strategy configuration to tell the Router what to do in case you navigate to the same URL as this user suggests in this GitHub issue.
First of all you can configure what to do while setting up the Router (your router module).
@NgModule({
imports: [RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload' })],
exports: [RouterModule]
})
Or, if you are like me and don't want to change the entire router module behaviour you can do it with a method/function like this:
reloadComponent() {
this._router.routeReuseStrategy.shouldReuseRoute = () => false;
this._router.onSameUrlNavigation = 'reload';
this._router.navigate(['/same-route']);
}
Of course you have to first inject Router in your component's constructor:
// import { Router } from '@angular/router';
...
constructor(private _router: Router){}
...
Somehow and as pointed out by @Abhiz you have to set shouldReuseRoute, with just configuring the Router by itself the page reload doesn't work with this aproach.
I've used an arrow function for shouldReuseRoutebecause new TSLint rules won't allow non-arrow functions.
Solution 2:[2]
This is the most simple solution if you just need to refresh the entire page
refreshPage() {
window.location.reload();
}
Solution 3:[3]
Without specifying the path you can do:
constructor(private route: ActivatedRoute, private router: Router) { }
reload() {
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
this.router.onSameUrlNavigation = 'reload';
this.router.navigate(['./'], { relativeTo: this.route });
}
And if you use query params you can do:
reload() {
...
this.router.navigate(['./'], { relativeTo: this.route, queryParamsHandling: 'preserve' });
}
Solution 4:[4]
import { DOCUMENT } from '@angular/common';
import { Component, Inject } from '@angular/core';
@Component({
selector: 'app-refresh-banner-notification',
templateUrl: './refresh-banner-notification.component.html',
styleUrls: ['./refresh-banner-notification.component.scss']
})
export class RefreshBannerNotificationComponent {
constructor(
@Inject(DOCUMENT) private _document: Document
) {}
refreshPage() {
this._document.defaultView.location.reload();
}
}
Solution 5:[5]
Because it's the same component. You can either listen to route change by injecting the ActivatedRoute and reacting to changes of params and query params, or you can change the default RouteReuseStrategy, so that a component will be destroyed and re-rendered when the URL changes instead of re-used.
Solution 6:[6]
I have solved by this way
import { Router, ActivatedRoute } from '@angular/router';
constructor(private router: Router
, private activeRoute: ActivatedRoute) {
}
reloadCurrentPage(){
let currentUrl = this.router.url;
this.router.navigateByUrl('/', {skipLocationChange: true}).then(() => {
this.router.navigate([currentUrl]);
});
}
Solution 7:[7]
Writing this as 2021 (Angular 12 running). Read explanation or jump to end for straight answer.
All the answers on this thread and others didn't help me quite much because of unwanted behaviour. What I did instead is implemented a hack.
Some light on existing answers
Angular will reload page which means Page Component/Resolvers/Guards in specific way.
using
this.router.onSameUrlNavigation = 'reload';
doesn't work most of the time because main purpose of it is to Re-enable Resolvers/Guards. Its mistaken for other meaning though.Also I didn't want to change this across as a global setting so nope!
Another way of window.location.reload() OR window.location.href=window.location.href
is worst possible way as it violates SPA rules. Downloading all chunks again is very bad solution.
While below solution works, for my usecase it was routing twice, so dropped this as well
this.router.navigateByUrl('', { skipLocationChange: true }).then(() => {
this.router.navigate(['/launchpad']);
});
Now the HACK / Solution
Why not tell angular its different route altogether, so reloading is taken care by Angular itself, it also covers guards, resolvers everything. For my usecase
In app-routing.module.ts I added same module with two different routes
one with '' empty route and one with say 'post-login'
{
path: '',
loadChildren: () => import('./post-login/post-login.module').then((m) => m.PostLoginModule),
canActivate: [AuthGuard],
},
{
path: 'post-login',
loadChildren: () => import('./post-login/post-login.module').then((m) => m.PostLoginModule),
canActivate: [AuthGuard],
}
Now inside wherever I want to reload the same page, Inject router: Router
and use simply like this
this.router.navigateByUrl(this.router.url.includes('post-login') ? '' : 'post-login');
This reloads page with alternate additional 'post-login' in Url but its fine for my usecase. Hope it helps :)
Solution 8:[8]
With angular 11 you can just use this:
in route config add runGuardsAndResolvers: 'always'
const routes: Routes = [
{ path: '', component: Component, runGuardsAndResolvers: 'always' },
];
and this is your method to reload:
reloadView(): void {
this.router.navigated = false;
this.router.navigate(['./'], { relativeTo: this.route });
}
this will trigger any resolver on that config
Solution 9:[9]
By this way we can preserve queryparams also
onReloadPage() {
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
this.router.onSameUrlNavigation = 'reload';
this.router.navigate(['./'], { relativeTo: this.activatedRoute, queryParamsHandling: 'preserve' });
}
Solution 10:[10]
I found a better way than reload the page. instead i will reload the data that just got updated. this way faster n better
Solution 11:[11]
Here is the simple one
if (this.router && this.router.url === '/') { or your current page url e.g '/home'
window.location.reload();
} else {
this.router.navigate([url]);
}
Solution 12:[12]
I believe Angular 6 has the BehaviorSubject object. My sample below is done using Angular 8 and will hopefully work for Angular 6 as well.
This method is a more "reactive" approach to the problem, and assumes you are using and are well versed in rxjs.
Assuming you are using an Observable in your parent component, the component that is used in your routing definition, then you should be able to just pulse the data stream pretty easily.
My example also assumes you are using a view model in your component like so...
vm$: Observable<IViewModel>;
And in the HTML like so...
<div *ngIf="(vm$ | async) as vm">
In your component file, add a BehaviorSubject instance...
private refreshBs: BehaviorSubject<number> = new BehaviorSubject<number>(0);
Then also add an action that can be invoked by a UI element...
refresh() {
this.refreshBs.next(1);
}
Here's the UI snippet, a Material Bootstrap button...
<button mdbBtn color="primary" class="ml-1 waves-dark" type="button" outline="true"
(click)="refresh()" mdbWavesEffect>Refresh</button>
Then, in your ngOnIt function do something like this, keep in mind that my example is simplified a bit so that I don't have to provide a lot of code...
ngOnInit() {
this.vm$ = this.refreshBs.asObservable().pipe(
switchMap(v => this.route.queryParamMap),
map(qpm => qpm.get("value")),
tap(v => console.log(`query param value: "${v}"`)),
// simulate data load
switchMap(v => of(v).pipe(
delay(500),
map(v => ({ items: [] }))
)),
catchError(e => of({ items: [], error: e }))
);
}
Solution 13:[13]
See this stackblitz which use a RouteReuseStrategy in combination with the onSameUrlNavigation: 'reload' Router option.
This strategy ensures that angular will always re-render the components when navigating to what it considers the "same" route (which includes having different path and query parameters).
@Injectable()
export class MyStrategy extends RouteReuseStrategy {
shouldDetach(route: ActivatedRouteSnapshot): boolean {
return false;
}
store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void {}
shouldAttach(route: ActivatedRouteSnapshot): boolean {
return false;
}
retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle|null {
return null;
}
shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
return false;
}
}
const routes = [
{path: '2', component: Empty2},
{path: '', component: Empty},
];
@NgModule({
imports: [ BrowserModule, RouterModule.forRoot(routes, {onSameUrlNavigation: 'reload'}) ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ],
providers: [{provide: RouteReuseStrategy, useClass: MyStrategy}]
})
export class AppModule { }
Solution 14:[14]
Setting shouldReuseRoute and onSameUrlNavigation properly on the router will force angular to reload when navigating on the same page, however as the router is a singleton, it might be relevant to set back its initial values after reloading the page.
This method below will backup and restore the router's settings to prevent side effects to occur. Please comment if you do have a cleaner solution to achieve the same.
class MyComponent {
constructor(private router: Router){}
public async reload(): Promise<boolean> {
const router = this.router;
const routeReuseStrategy = router.routeReuseStrategy.shouldReuseRoute;
const onSameUrlNavigation = router.onSameUrlNavigation;
try {
router.routeReuseStrategy.shouldReuseRoute = () => false;
router.onSameUrlNavigation = 'reload';
return await router.navigateByUrl(router.url);
} finally {
router.routeReuseStrategy.shouldReuseRoute = routeReuseStrategy;
router.onSameUrlNavigation = onSameUrlNavigation;
}
}
}
Solution 15:[15]
For child and main component, I have written the following code to reload the page
reloadCurrentRoute() {
let currentUrl = this.router.url;
this.router.navigateByUrl('/', {skipLocationChange: true}).then(() => {
this.router.navigate([currentUrl]);
});
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow

