1

I'm using the pattern from RxJs like so.

serviceThatMayNotComplete
  .obtainObservableOfSomeKind(url)
  .subscribe(res => console.log(res));

When the component is done, I understand that I need to unsubscribe to avoid memory leaks. Since I know that the service will only produce a single value, ever, I tried to find a version of subscribe that only picks one element (a bit like the promisses did).

I've located take and first but it seems that they are operators on the set to be emitted and not how the consumption is performed.

Googling gave little I recognized as helpful but I might be using poor key words.

Is there a version of subscribe that dies after a single response being delivered?

DonkeyBanana
  • 3,266
  • 4
  • 26
  • 65
  • 1
    you don't need to unsubscribe to to http-requests. They complete. – AT82 Aug 29 '19 at 18:24
  • 1
    angular source code: https://github.com/angular/angular/blob/master/packages/common/http/src/xhr.ts#L217 – AT82 Aug 29 '19 at 18:29
  • @AJT_82 That was just an example that I took off the top of my head (possibly poor choice). What if an emitter don't complete (in particular, if it doesn't complete while it should but is sloppily implemented, hence letting the hangaroo be left alive)? – DonkeyBanana Aug 29 '19 at 19:06
  • well, then that was indeed a poor example in this case :P since http-requests do complete themselves. But if you were to use some kind of subject, it won't, then you need to unsubscribe in some way ;) – AT82 Aug 29 '19 at 19:13
  • @AJT_82 The poorness corrected. Thanks. Do you have any opinion on the quality of the two answers provided? (One being `pipe(take(1))` and the other `first()`.) – DonkeyBanana Aug 29 '19 at 19:17
  • Well, I guess it depends on the case... here you can read about the difference: https://stackoverflow.com/questions/42345969/angular-2-using-rxjs-take1-vs-first I don't think that in this case it really matters which you use. Personally, I would probably favor `take(1)` :) – AT82 Aug 29 '19 at 19:27
  • @AJT_82 I appreciate the link and will read it immediately. While I understand that the actual choice is subject to case specific predispositions, I'm curious what made you put a vote on `take`. Is it just a force of habit or are you seeing something I'm not? – DonkeyBanana Aug 29 '19 at 20:36
  • It's more of a habit, that is actually true. But also in these case, if you were to use a subject to pass around some data that should be shared over several components, is error handling really needed? I'd say no, and since the main difference between `first()` and `take(1)` is that `first()` triggers error when something bad happens. – AT82 Aug 30 '19 at 07:23

2 Answers2

2

Mix together pipe operator and take(1), this should get you the first value and then unsub automatically.

http.get(url)
 .pipe(take(1))
 .subscribe(res => console.log(res));

In such scenarios we can use RxJS take(1) operator which is great because it automatically unsubscribes after the first execution.

Mentioned in this article

Also, be aware, when using angular's default HttpClient for that get request, the cleanup is already taken care of by the framework for you.

Stavm
  • 7,833
  • 5
  • 44
  • 68
devDan
  • 5,969
  • 3
  • 21
  • 40
  • Why do you post identical answers? From my undestanding, if you find that two questions are similar on Stack, you should mark as duplicate instead? https://stackoverflow.com/a/57715709/6294072 – DRNR Aug 29 '19 at 18:38
  • @DRNR I disagree that the dupe marker here would be beneficial. Even if we can argue that the content of it embraces my issue as well, it's far from apparent. – DonkeyBanana Aug 29 '19 at 19:09
  • I'm going to remove it shortly fear not – devDan Aug 29 '19 at 19:10
  • @dince12 Please don't. It's going to be less apparent. Also, you might want to throw in a word on the difference between your suggestion and the one below with `first()`. – DonkeyBanana Aug 29 '19 at 19:12
1

If you only want to observe the first value, then you can use first()

Assuming that http.get() returns a observable, you can do:

http.get(url).first().subscribe(
//your code
);

Note:

first() will unsubscribe automatically when their condition is met.

Yash
  • 3,438
  • 2
  • 17
  • 33
  • And what condition is it in the case of no parameter value being passed in? And I'm a bit confused how it differs from the suggestion above with `pipe(take(1))`. Would you care to elaborate, please? – DonkeyBanana Aug 29 '19 at 19:11