YoNuevo
YoNuevo

Reputation: 117

how to subscribe to observable whose input depends on data from other observable

In my Angular app I have a component whose data depends on a route parameter. When the page opens the first time the data is loaded correctly. When I change to a different page but stay on the same component (so only one route parameters change) the new data is not loaded.

the routeparameters are updated and all the data that is being subscribed to with the async pipe is loaded correctly. there is however one piece of data that needs extra handling. this observable is being subscribed to in the component. this is the one with data that isnt loaded again.

In the code below the build-in paramMap observable subscription keeps on tracking changes to the route parameters and running the callback. the second observable doesnt. I suppose this is because the second observable is completed and is actually replaced by a new one which is never subscribed to (in the fist callback).

how to best handle this problem to also get the data from the second observable?

The only thing that seems to make it work is to move this second subscription to the callback of the first. but that doesnt look to very clean code to me and I'm not certain what would happen if for some reason the observable doesnt complete by the time it is replaced by the new one.

ngOnInit(): void {
  this.route.parent.paramMap.subscribe((paramMap: ParamMap) => {
    this.id = paramMap.get('id');
    this.observable= this.service.getSomething(this.id);
  }
  this.observable.subscribe(
    // callback that handles the processing of the data
  )
}

Upvotes: 0

Views: 1546

Answers (3)

RetBack
RetBack

Reputation: 81

I could imagine that you want to do something like below (rxjs v6):

  ngOnInit(): void {
    this.route.parent.paramMap.pipe(
      map(paramMap: ParamMap) => this.id = paramMap.get('id'),
      mergeMap(id => this.service.getSomething(this.id))
    )
      .subscribe(
        // callback that handles the processing of the data
      )
  }

so whenever the params changes the whole pipe gets triggered and the service gets called.

Upvotes: 1

user4676340
user4676340

Reputation:

Use operators :

ngOnInit() {
  this.observable = this.route.parent.paramMap.pipe(
    map(paramMap => paramMap.get('id')),
    switchMap(id => this.service.getSomething(id))
  );
}

switchMap will cancel pending requests.

If you want to keep them active, use mergeMap.

Upvotes: 0

smtaha512
smtaha512

Reputation: 450

You can use switchMap operator form RxJS here like:

ngOnInit(): void {
    this.route.parent.paramMap.pipe(switchMap((paramMap: ParamMap) => {
      this.id = paramMap.get('id');
      return this.service.getSomething(this.id);
    })).subscribe(
        // callback that handles the processing of the data
      );
}

Upvotes: 1

Related Questions