-1

I have this working code. It fetches the ID from the router and applies it as a parameter to get load in the data for the component.

this.route.params.subscribe(_ => {
  this.id = _.id;
  this.service.getMineral(this.id)
    .subscribe(suc => this.data = suc, err => console.log(err));
  }
);

Then, I tried to play around with better approaches and want to invoke the second subscription when the first one completes. According to the second sample in this answer, I'm supposed to share the first result and then switch map to unsubscribe from it and proceed with the next one. So I implemented the following.

const route$ = this.route.params.pipe(share());
const data$ = route$.pipe(
  switchMap(() => this.service.getMineral(this.id)));

route$.subscribe(_ => this.id = _.id);
data$.subscribe(suc => this.data = suc, err => console.log(err));

Regrettably, this makes no call to the server and no data is delivered to the client. After trying several alterations, I gave up, due to lack of ideas.

What's the significant difference between those two approaches? Where do I get confused on my interpretation of the second sample?

Konrad Viltersten
  • 36,151
  • 76
  • 250
  • 438

1 Answers1

1

I think your approach is bad. You should chain it in one observable and subscribe to it. Something like

 this.route.params.pipe(
    switchMap(params => this.service.getMineral(params.id))).subscribe()  
Adamicov
  • 126
  • 4
  • I think my approach is bad too. It's kind of implied by the fact that it fails. As for your suggestion - I wonder where in the code you're setting the ID from the params to a local property. Or am I missing something? I also wonder if the approach suggested in the linked answer is flawed too or if I simply didn't follow it correctly. – Konrad Viltersten Feb 08 '20 at 23:16
  • I made a mistake, that's params.id instead this.params.id. Sorry for confusion. I'm not sure about solution you have sent. I think above code should work. – Adamicov Feb 09 '20 at 01:12
  • Next level for RxJS in Angular is to never subscribe :) Consume your streams in the template with an `async` pipe. And then turn on `ChangeDetectionStrategy.OnPush`. That way, the stream will never leak memory and you will have good performance. `
    {{data$ | async}}
    `
    – blid Feb 09 '20 at 10:20
  • @blid That sounds like something I'd like to implement in my projects. Are you saying that the sample in this answer is as supposed to but that we can omit the *subscribe()* part and use *async* pipe in the template straight off? I fear that it's a nice approach in theory and for simple cases. Then, this nasty reality happens and we have a bunch of edge cases that make it too complex and difficult to maintain in the long run, though... – Konrad Viltersten Feb 09 '20 at 16:05