Nico
Nico

Reputation: 313

Angular route to same component with different parameters

I have a component that can route to itself but with different route parameters.

As you probably know this wont fire the constructor or ngOnInit.

To get around this I have the following in my constructor

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

This solve the problem but I realize that my routes go crazy when using it. For instance a link to a totally different route becomes active and when I hover over it, it seems to have changed from the url it should be to the current URL. (hard to describe)

Upvotes: 6

Views: 15890

Answers (2)

Steve Land
Steve Land

Reputation: 4862

I'd suggest an alternative approach - overriding the Angular routing logic is likely to be error prone (as you've already discovered), and I'm fairly sure that you should be able to achieve what you're after in other, simpler ways.

One way would be writing a setup method that you can call when you need to setup (or reset) your component and then subscribing to the params observable on the ActivatedRoute, using that event to call your setup method - like this:

import { Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-test',
  templateUrl: './test.component.html',
  styleUrls: ['./test.component.css']
})
export class TestComponent {

  setupMessage = 'not set up yet';
  someParameterValue = null;

  constructor(private activateRoute: ActivatedRoute) {
    activateRoute.params.subscribe(params => {
      this.setupComponent(params['someParam']);
    })
  }

  setupComponent(someParam) {
    this.setupMessage = 'set up at ' + new Date();
    this.someParameterValue = someParam;
  }
}

Here is a working stackblitz demo of this.

Upvotes: 16

Alf Moh
Alf Moh

Reputation: 7427

Changing the shouldReuseRoute function to just return false is what might be causing the problem. You can try this.

  shouldReuseRoute(
    future: ActivatedRouteSnapshot,
    curr: ActivatedRouteSnapshot
  ): boolean {
    return curr.routeConfig === null && future.routeConfig === null;
  }

As a matter of fact, you re-implement the RouteReuseStrategy class. Had a similar problem and had help from github but unfortunately I can't remember the link.

This is how it will look like.

customReuseRouteStrategy.ts

import {
  ActivatedRouteSnapshot,
  DetachedRouteHandle,
  RouteReuseStrategy
} from "@angular/router";

export class CustomRouteReuseStrategy implements RouteReuseStrategy {
  shouldDetach(route: ActivatedRouteSnapshot): boolean {
    return false;
  }
  store(
    route: ActivatedRouteSnapshot,
    detachedTree: DetachedRouteHandle
  ): void {}
  shouldAttach(route: ActivatedRouteSnapshot): boolean {
    return false;
  }
  retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
    return null;
  }
  shouldReuseRoute(
    future: ActivatedRouteSnapshot,
    curr: ActivatedRouteSnapshot
  ): boolean {
    return curr.routeConfig === null && future.routeConfig === null;
  }
}

Then in your module providers, you will replace RouteReuseStrategy with the class you just created.

yourmodue.module.ts

 providers: [
    {
      provide: RouteReuseStrategy,
      useClass: CustomRouteReuseStrategy
    }
  ]

Upvotes: 0

Related Questions