Rxjs: take and takeLast don't work for Subject

Created on 10 Dec 2016  路  6Comments  路  Source: ReactiveX/rxjs

take and takeLast don't work for Subject but works for Observable.

Checked versions: 5.0.0-beta.12, 5.0.0-rc.4, 5.0.0-rc.5

Works properly for Observable:

let observable = Observable.of('first', 'second', 'third');
observable.subscribe(s => console.log(s));
observable.take(1).subscribe(s => console.log(s));

Actual result::

second
third
first

Does not work for Subject

let subject = new Subject<string>();
subject.subscribe(s => console.log(s));
subject.next('first');
subject.next('second');
subject.next('third');
subject.take(1).subscribe(s => console.log(s));

Expected result should be as in Observable example above.
Actual result:

second
third

Even if you add setTimeout for avoiding potential callback issues, result will not changes.

Most helpful comment

Subjects are hot by default, so the three events have already passed by once you subscribe the second time.

If you change things around, you'll get the behavior you're looking for.

let subject = new Subject<string>();
subject.subscribe(s => console.log(s));
subject.take(1).subscribe(s => console.log(s));
subject.next('first');
subject.next('second');
subject.next('third');

All 6 comments

Subjects are hot by default, so the three events have already passed by once you subscribe the second time.

If you change things around, you'll get the behavior you're looking for.

let subject = new Subject<string>();
subject.subscribe(s => console.log(s));
subject.take(1).subscribe(s => console.log(s));
subject.next('first');
subject.next('second');
subject.next('third');

@david-driscoll has the correct answer here. Since subject try to synchronously emit values that are next-ed into them, if you subscribe after you've done all of your next-ing, it's not going to push any values through that new subscription, therefore take(1) never saw a value to take.

I'm closing this one for now. If you have more questions or feel this was in error, feel free to open another issue or comment again in here.

Thanks @vladbrk!

@david-driscoll @blesh thanks for answers but what about takeLast, how to make it works. Even if I shift it before calls next, it will not works.

takeLast waits until observable completes. In above snippet, subject never completes so takeLast won't pick any values.

@kwonoj thanks. After reading about hot/cold Observable and observer.onCompleted() I figured out how it works.

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

cartant picture cartant  路  3Comments

Agraphie picture Agraphie  路  3Comments

giovannicandido picture giovannicandido  路  4Comments

Zzzen picture Zzzen  路  3Comments

benlesh picture benlesh  路  3Comments