0

Here's my code snippet(example)

fetchData(): void {
    if (this.subscription$) {
        this.subscription$.unsubscribe();
    }
    this.subscription$ = this.store.select('someEvent')
                                   .subscribe(data => {
                                      console.log(data);
                                   });
}

ngOnDestroy() { 
  this.subscription$.unsubscribe();
}

I need to call the fetchData method to add another subscription to get the current state from store. So at this point, I've implemented it like above in order to free up the previous subscription. It works the way I wanted it to work but I feel like the code is not neat. I was digging into takeUntil and takeWhile to make code more Rx way but I didn't make it.

DongBin Kim
  • 1,799
  • 5
  • 23
  • 43
  • if your component not destroy. you have no any needs for destroy subscription. because `this.store.select` called again and replace subscription not create new subscription. – Shailesh Ladumor Dec 28 '17 at 06:58
  • so i think its not take new memory. – Shailesh Ladumor Dec 28 '17 at 06:59
  • Possible duplicate of [Angular/RxJs When should I unsubscribe from \`Subscription\`](https://stackoverflow.com/questions/38008334/angular-rxjs-when-should-i-unsubscribe-from-subscription) – dee zg Dec 28 '17 at 07:35
  • 1
    @ShaileshLadumor I'm afraid you are wrong. I've tested it out and it subscription stays alive as I expected. Just the variable `subscription$` is replaced. – DongBin Kim Dec 28 '17 at 08:26
  • @deezg I've already checked out the question and this is a different case. – DongBin Kim Dec 28 '17 at 08:27
  • 1) why do you need to change subscription in your `fetchData` method? 2) how many different subscriptions you have that you're switching between? – dee zg Dec 28 '17 at 08:31
  • @deezg I don't necessarily have to change the subscription but I implemented that way to get the current state of application from `store`. I cannot anticipate how many subscriptions would be generated. It will depend on the situation. – DongBin Kim Dec 28 '17 at 08:52
  • ok, let me rephrase: what makes you need to kill old subscription and introduce a new one? asking because, in a regular usage of the store, you don't need to do that. nor you need to 'ask for data'. that's the whole point of observable, you subscribe once and as data changes, you'll get notified. so, please explain a bit your reasons behind re-subscribing. – dee zg Dec 28 '17 at 08:55
  • @deezg Okay, I think I've got your point. 1) The reason I need to kill the old subscription is otherwise, the old subscription stays alive and keeps getting the data which is likely to cause bugs. 2) I understand how observables work and the beauty of it but this case, as I explained above, I need to get the latest state/value which the `store` is keeping. In order to get it, I decide to register the subscription again because in that way, the store in Angular emits the current state which it's holding at that moment. – DongBin Kim Dec 28 '17 at 09:05
  • @deezg There may be a different way to get the current state/value of application from `store` but this approach(adding a new subscription) is what I'm taking. Walk me through if you have any idea – DongBin Kim Dec 28 '17 at 09:07
  • subscribe to your `store.select` in your constructor, so only once. within your subscribe method, you can set your private field to last received data from subscription: `...subscribe(data => { this.myData = data;})` and you'll always have last state of the store in your `this.myData` field. resubscribing over and over again you're defeating the whole purpose of observables. maybe there are some reasons for this behind my understanding, but from what i understand so far, you just don't need resubscribe at all. – dee zg Dec 28 '17 at 09:13
  • btw, it sounds like there might be a need for clarification: 'old subscription' doesn't mean old data. – dee zg Dec 28 '17 at 09:14
  • @deezg Actually, that's what I've tried before I took this approach. "Keeping the latest state/value in the component with a local variable". Then I was thinking, 'Is it good to keep the state/value in a component?" I understand resubscribing over times could miss the beauty of using observables. I just don't know which way is more proper. – DongBin Kim Dec 28 '17 at 09:23
  • you are not keeping state in component that way. state is kept in the store. with private field, you're using it in the component. you're just resolving (unwrapping) it from observable to usable underlying data. that is, of course, for the case you don't use `async` pipe in your template. if you were using `async` pipe, then pipe does all of that for you and you get unwrapped data ready to be used. – dee zg Dec 28 '17 at 09:29
  • @deezg Understood. I guess I will need to rethink about it. Thanks man! – DongBin Kim Dec 28 '17 at 09:35
  • i'm glad if it helped. google for `dumb/smart components` in context of angular. `ngrx/store` & `async` pipes fit very nicely into that pattern and you'll get a very powerful way to build apps. – dee zg Dec 28 '17 at 09:46

1 Answers1

0

Use a subject to signal destruction

destroyed$=new Subject()
 fetchData(): void {
this.store.select('someEvent').takeUntil(destroyed$)
                               .subscribe(data => {
                                  console.log(data);
                               });
}

ngOnDestroy() { 
   destroy$.next()
}
Fan Cheung
  • 10,745
  • 3
  • 17
  • 39
  • Appreciate your answer but the thing is I cannot wait till the component gets destroyed because the `fetchData` method is going to be called a few times, which means there will be several subscriptions alive. That's why I added `if clause` above to free up the previous one. – DongBin Kim Dec 28 '17 at 06:58
  • do you mean the code should fullfill one more requirement that only one fetchData is allow to run at any given time – Fan Cheung Dec 28 '17 at 07:15
  • No, calling the `fetchData` method several times is totally fine. What I'm wondering is if there's a way to make the unsubscribe code tidy rather than doing it manually like I did above – DongBin Kim Dec 28 '17 at 08:30
  • In a good Rxjs pattern there's should be a minimal number of subscription needed in a controller. what you normally do is return observable from function() and merge, concat them into a main function that subscribe once. If you have too many subscription sitting around often hint the code can be done better. – Fan Cheung Dec 28 '17 at 08:59
  • I understand what you mean. However, since this is just one observable called possibly over times, I cannot see any way how/why I would merge or concat them. – DongBin Kim Dec 28 '17 at 09:27