Update content when changing the URL parameter with routerLink in Angular 7

Question:

I am working with Angular 7 and changing the URL parameter does not update the content because it does not reload the constructor or the ngOnInit, all URLs call the same components for example CategoryComponent but depending on the URL parameter it shows some products or others.

I explain it better with code.

Router component.

const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: ':category', component: CategoryComponent },
  { path: '**', component: Error404Component }
];

I have a menu with a dropdown-menu

<div class="dropdown-menu" aria-labelledby="dropdownMenuCategory">
  <a class="dropdown-item" [routerLink]="['/robots-aspiradores']">Robots Aspiradores</a>
  <a class="dropdown-item" [routerLink]="['/patinetes-electricos']">Patinetes Eléctricos</a>
  <a class="dropdown-item" [routerLink]="['/cafeteras']">Cafeteras</a>
</div>

CategoryComponent Constructor

constructor( private _activatedRoute: ActivatedRoute, private _productService: ProductService ) {
    this.url = GLOBAL.url;
    this.categoryName = this._activatedRoute.snapshot.paramMap.get("category")
    this.getProductsCategory(this.categoryName);
    this.title = this.categoryName.replace('-', ' ').toUpperCase();
  }

I want that when each menu option is clicked I reload the constructor or ngOnInit but it only loads the first time I enter but if I move from one category page to another it does not reload I have to go to HOME and enter to another category to reload.

I don't know if I explained myself well, I hope so, greetings and thanks.

Answer:

The first thing is to understand the life cycle of Angular components, so here is an article that explains it in detail .

I will focus here on what is important: Angular does not destroy a component to create one of the same type in the same place, simply when the URL changes, the change detection cycle is executed.

So we have a component that is loaded with the URL "/:category" , where that :category is a variable parameter. Since the component's constructor is only executed when an instance is created and your constructor looks like this:

constructor( private _activatedRoute: ActivatedRoute, private _productService: ProductService ) {
    ...
    this.categoryName = this._activatedRoute.snapshot.paramMap.get("category")
    this.getProductsCategory(this.categoryName);
    ...
}

It turns out that you only look at the path once (get the current path, a snapshot , and act accordingly (loading the corresponding category).

But when the parameter varies, your component doesn't know about it because it isn't observing (not subscribing to) the parameter changes. He looked at it once and forgot about it

Therefore, I advise you to make the following changes:

export class CategoryComponent implements OnInit {

  //atributos
  category: string;
  title: string;
  url = GLOBAL.url;

  constructor( 
      private _activatedRoute: ActivatedRoute,
      private _productService: ProductService ) {
    //nada de código con lógica de angular aquí, es lo recomendado
  }

  ngOnInit() {
    this._activatedRoute.paramMap.subscribe((params: ParamMap) => {
      this.category = params.get('category');
      this.getProductsCategory(this.categoryName);
      this.title = this.categoryName.replace('-', ' ').toUpperCase();
    }
  }

  ... //resto de código
}

In this way any change in the URL will be detected by the component and it will act as the first time.

Scroll to Top