-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Request for takeUntil with predicate function #2420
Comments
It's funny that last week I've encountered exactly the same thing and I was wondering if I'm just dumb or there's really no easy way to do this. I ended up using the following:
This produces the result you want but is very confusing and inefficient. |
Thanks @martinsik, that's pretty clever. I still think an operator would be nice, especially since there's precedent in RxJava. I'll keep this as a workaround though. |
Thanks to http://stackoverflow.com/a/35800173/1709679 I figured out how to make it with work with const takeWhileInclusive = predicate => source =>
new Observable(observer => {
const subscription = source.subscribe({
next: value => {
observer.next(value);
if (!predicate(value)) {
observer.complete();
}
},
error: error => observer.error(error),
complete: () => observer.complete()
});
return () => subscription.unsubscribe();
});
Observable.of("red", "blue", "green", "orange")
.let(takeWhileInclusive(color => color !== "green"))
.subscribe({ next: value => console.log(`takeWhileInclusive: ${value}`) }); Working example: http://jsbin.com/mekupugeza/edit?js,console |
also possible w/ multicast: Observable
.of("red", "blue", "green", "orange")
.multicast(
() => new ReplaySubject(1),
(colors) => colors.takeWhile((c) => c !== 'green').concat(colors.take(1))
) |
I understand that you don't want to add too many operators to avoid bloat and confusion, but I would love to see an operator similar to |
Great stuff that the multicast works, thanks for that. It's fairly verbose and doesn't come to mind when I'm thinking of how I can compose current operators to achieve it :( It's even more verbose with lettables: Observable
.of("red", "blue", "green", "orange")
.multicast(
() => new ReplaySubject(1),
(colors) => colors.pipe(
takeWhile((c) => c !== 'green'),
concat(colors.pipe(
take(1),
)),
),
) I'm using takeWhileInclusive in probably every project and giving a +1 here. Perhaps there's a better way but I'm needing it commonly for countdowns as well: // Countdown time left until next turn
countdown$ = this.game$.pipe(
map(game => game.scheduledAt),
switchMap(time => {
return timer(0, 16).pipe(
map(() => {
const diff = time - Date.now();
return diff < 0 ? 0 : diff / 1000;
}),
takeWhileInclusive(v => v > 0),
);
}),
); |
I use it also very often. Would love to see it as operator out of the box |
For now I've created a library for this operator that can be found here: https://www.npmjs.com/package/rxjs-take-while-inclusive. |
I've run into an issue several times where I'm using
takeWhile
but I also want to include the last element from the source observable that triggered the predicate function. For example:gives me:
but I want:
I haven't found a graceful way to compose this behavior using existing operators. Ideally, I would like to have a derivative of
takeWhile
that adds an additional call tonext()
here: takeWhile.ts#L85RxJava 1.x implemented this by overloading takeUntil to also take a predicate function. You can find the thread discussing this here.
Let me know if there's any interest in this. I'd be happy to put together a PR.
The text was updated successfully, but these errors were encountered: