11
votes

In the ngOnDestroy method, I unsubscribe from an observable which I subscribed to once else the code is multiple times executed...

ngOnInit()
{
    this.sub = this.route.params.subscribe(params => 
    {
        this.projectId = +params['id'];
        this.projectStore.project = this.projectId;

        // load data when the route changes
        this._tasksService.gettasks(this.projectId).subscribe(years => { this.tasks = years.map(y => new task(y)) }); // no need to clean up the subscription

    });
    // load data when the component is initialized
    this._tasksService.gettasks(this.projectId).subscribe(years => { this.tasks = years.map(y => new task(y)) }); // no need to clean up the subscription

}

ngOnDestroy()
{
    this.sub.unsubscribe();
}

Now I want to put this in a router resolve class but there is no ngOnDestroy - of course - just a NavigationEnd event which I again could subscribe to.

That means I subscribe to a NavigationStart event (which occurs when I leave the route) in order to unsubscribe another subscription which is the route params change subscription HAHAHA...

I guess that's not the way to go, but Google offered nothing.

Anyone knows how to tackle that scenario? Or should route params change subscription really ONLY belong into a component?

  constructor(private service: TasksService, private router: Router)
  {

   this.navigationEnded = this.router.events
      .filter(event => event instanceof NavigationStart)
      .map(() => this.router.routerState.root)
      .subscribe((event) =>
      {
         this.navigationEnded.unsubscribe();
      });
  }

UPDATE

When I put this code in the resolve method:

  this.route.params.subscribe(params => 
    {
         // reload data by the new id parameter does not work with params
         // I have to use inside here: route.params['id']
    });

there is no id in the params array, its just of length 0.

Instead, I have to use route.params['id'] inside the params subscription, but why?

1
It's not entirely clear to me what the problem is or what you actually try to accomplish. Why do you think you need to unsubscribe? The router injected to a service is the root router and this router will stay the same the whole application lifetime.Günter Zöchbauer
I try to accomplish: I want to put the working code from ngOnInit/ngOnDestroy into a router resolve class and the behavior should be the same without router resolve class.Pascal
I would like to use the resolve feature because the loading of the data and then activating the route`s view has better enduser UX.Pascal

1 Answers

9
votes

You can just use the first() operator. This way the observable completes after the first event. No need to unsubscribe this way:

this.router.events
  .filter(event => event instanceof NavigationStart)
  .map(() => this.router.routerState.root)
  .first()
  .subscribe((event) =>
  {
     //this.navigationEnded.unsubscribe();
  });