17

I'm trying to reload my navigations in my angular 5.2 application without any success. If the params are unchanged, the angular router will ignore my navigations.

How I navigate:

this.router.navigate(['/search', buildParamsFromSearchCriteria(criteria)]);

This navigates to:

/search;pageSize=20;page=1;orderBy=price;sortDirection=ASCENDING

My module config:

imports: [RouterModule.forRoot(appRoutes, { preloadingStrategy: PreloadAllModules, enableTracing: false, onSameUrlNavigation: 'reload' })],
Guerric P
  • 30,447
  • 6
  • 48
  • 86
heldt
  • 4,166
  • 7
  • 39
  • 67
  • 1
    Did you see that thread? https://github.com/angular/angular/issues/21115 Apparently,it's only used torun again guards and resolvers. What are you trying to achieve exactly? Can't you just have a 'refresh' action in your component that you could call manually? – David Mar 05 '18 at 08:18
  • I can't have a refresh because my component only navigates with the search params. My ngrx effects listens to the router calls and dispatches a search-action on navigation to the url. I have a temporary hack now that sets a random number at the end of the url to make it unique – heldt Mar 05 '18 at 14:49
  • Why would you route on the same url twice? You would get the same result? – ochs.tobi Mar 06 '18 at 12:13
  • The result may not be the same because the backend data may have been updated or items may have been added. – heldt Mar 06 '18 at 12:24
  • You could add one more random parameter to force refresh. – kemsky Mar 08 '18 at 15:46
  • is a simple `window.location.reload(true);` an option? – lukas-reineke Mar 09 '18 at 18:19
  • @lukas-reineke I don't want to reload page. It would result in restarting my single page application. – heldt Mar 14 '18 at 14:17
  • ```router.routeReuseStrategy.shouldReuseRoute = function () { return false; };``` – Bhargav Reddy Nov 07 '19 at 13:34
  • Check this solution work every times for me.[https://stackoverflow.com/questions/48070404/angular-5-route-animations-for-navigating-to-the-same-route-but-different-para/49162885](https://stackoverflow.com/questions/48070404/angular-5-route-animations-for-navigating-to-the-same-route-but-different-para/49162885) – Mehdi Bekkouche Jan 21 '20 at 08:53

3 Answers3

3

It can be done in a much simpler way. Below is a small sample code:

in routing.module: "/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 load
    ngOnInit() {
    }

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

the general explanation is ... why to destroy already existed component instance and create a new one for the same case when it means performance degradation? It is the exactly the same behavior as using routes pattern /product/:id where the same component instance is also kept for /product/5, /product/6, ...

So you should re-init the component on the base of some emitted event (resolver/guard) and not on the base of OnInit hook because of the same component instance.

  • I had tried this approach but in the case of navigation to the route having the same param. It won't trigger an event for the `this.route.params.subscribe(params => ` – Saurabh Gangamwar Nov 03 '21 at 18:41
0

I've come across the same problem when trying to refresh a page when clicking on its associated button on the navbar.

As stated in the comments, onSameUrlNavigation only runs guards and resolvers, but do not reinitialize components. The interesting part is that it also triggers a navigation.

So I created an abstract class that reacts to the NavigationEnd event:

/**
 * Abstract class that allows derived components to get refreshed automatically on route change.
 * The actual use case is : a page gets refreshed by navigating on the same URL and we want the rendered components to refresh
 */
export abstract class AutoRefreshingComponent implements OnInit, OnDestroy {
  public routerEventsSubscription: Subscription;
  protected router: Router;

  constructor() { 
    this.router = AppInjector.get(Router);
  }

  /**
   * Initialization behavior. Note that derived classes must not implement OnInit.
   * Use initialize() on derived classes instead.
   */
  ngOnInit() {
    this.initialize();
    this.routerEventsSubscription = this.router.events.filter(x => x instanceof NavigationEnd).subscribe(res => {
      this.initialize();
    });
  }

  /**
   * Destruction behavior. Note that derived classes must not implement OnDestroy.
   * Use destroy() on derived classes instead.
   */
  ngOnDestroy(): void {
    this.routerEventsSubscription.unsubscribe();
    this.destroy();
  }

  /**
   * Function that allows derived components to define an initialization behavior
   */
  abstract initialize(): void;

  /**
   * Function that allows derived components to define a destruction behavior
   */
  abstract destroy(): void;

}

AppInjector refers to this:

import {Injector} from '@angular/core';

/**
 * Allows for retrieving singletons using `AppInjector.get(MyService)` (whereas
 * `ReflectiveInjector.resolveAndCreate(MyService)` would create a new instance
 * of the service).
 */
export let AppInjector: Injector;

/**
 * Helper to access the exported {@link AppInjector}, needed as ES6 modules export
 * immutable bindings; see http://2ality.com/2015/07/es6-module-exports.html
 */
export function setAppInjector(injector: Injector) {
    if (AppInjector) {
        // Should not happen
        console.error('Programming error: AppInjector was already set');
    }
    else {
        AppInjector = injector;
    }
}

And in the AppModule:

import { setAppInjector } from './app.injector';

// ...

export class AppModule {
  constructor(private injector: Injector) {
    setAppInjector(injector);
  }
}

Then I made all of my needed components extend AutoRefreshingComponent and implement needed functions.

Hope this late answer helps.

Guerric P
  • 30,447
  • 6
  • 48
  • 86
0
this.router.navigated =false
work for me  then at ngOnInit just put this below code
this._initise = this.router.events.pipe(
  filter((event: RouterEvent) => event instanceof NavigationEnd),
  takeUntil(this.destroyed)
).subscribe(() => {
  this.router.navigated = false;
  console.log('initialiseInvites')
  this.initialiseInvites();
});