-1

I have the below code in the constructor of my component

this.performanceKpaId = parseInt(
  this.route.snapshot.paramMap.get('id') ?? '0',
  10
);

// get entity by id and render
this.getPerformanceKPA();

This code allows me to route to the component with an Id at the end of the URL and then the component gets the entity with that Id from the database and renders it.

My route path looks like this

  {
    path: 'kpa/:id',
    component: ViewPerformanceKpaComponent,
  },

I have requirements to have prev and next buttons on the page. Upon clicking next or prev, I have tried using the below code:

this.router.navigate([`/partners/performance/kpa/${idOfNextEntity}`]);

This results in the URL updating, but the component does not re-initialize. Therefore the url has id 2 in it but the page is still rendering entity with id 1.

I have a workaround whereby I explicitly call the database and get the new entity and render it when the user clicks next or prev, but I would ideally like it so that when I call router.navigate, it results in the component re-initializing. I need this because if the user clicks next 5 times and then tries to click back using their browser navigation button, they have to click it five times before anything even happens. The URL changes to the previous one but the component is not-re-initialised.

I understand this is happening because the route is not actually changing, just the path variable in the route, but is there a way I can force Angular to re-init the component even if only the path variable changed in the route?

1

1 Answer 1

0

this.route.snapshot only gives you a snapshot. When only the path params change, the components are recycled, so the component isn't created again, which is a very good thing for the application performance. Instead of working with the snapshot, use this.route.paramMap observable to subscribe to the changes (Also don't forget to unsubscribe):

export class MyComponent implements OnDestroy {
  private destroy$ = new Subject<void>();

  constructor(private route: ActivatedRoute) {
    this.route.paramMap
      .pipe(takeUntil(this.destroy$))
      .subscribe(params => {
        this.performanceKpaId = parseInt(params.get('id') ?? '0', 10);

        // get entity by id and render
        this.getPerformanceKPA();
    });
  }

  ngOnDestroy() {
    this.destroy$.next();
    this.destroy$.complete();
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Don't do this...it is a memory leak. At a minimum make a named object and destroy it in ngOnDestroy. You would be better doing this type of work in the ngOnInit which does trigger every time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.