I have this observable subscribtion
this.tooltipEventSubject.pipe(
filter(event => event.type === "show"),
tap(() => this.tooltipContent.loading = true),
filter(() => this.messageContent?.sender !== undefined && this.tooltipContent.success === undefined),
mergeMap(() => this.jabService.searchEntityInAddressBook(this.messageContent?.sender ?? "")),
mergeMap(response => response.values),
filter(response => response !== undefined) as OperatorFunction<Entity | undefined, Entity>,
tap(() => console.log("before first")),
find(entity => entity.name === this.messageContent?.sender),
tap(() => console.log("after first")),
).subscribe({
next: () => console.log("next"),
error: err => console.log(err),
complete: () => console.log("complete")
})
It hits the "find" predicate (checked with debugger) and then does nothing.
I have tried a lot of operators, like first following by a catchError, here on this example I have find.
It is getting to "before first", but then it won't print anything else. I am aware that the find predicate is returning false, and it should. But why does it stop running ? Shouldn't it return "undefined" to the following operators ? And shouldn't it even print "complete" ?
Thank you for your answers
CodePudding user response:
find
operator will wait until predicate returns true and till then it will not emit any data even undefined
.
find
will emit undefined
only when source observable
completes and none of the data match.
In your case source observable is a form event,So it will not be completed unless you do.Ex.takeUntil ..
I am providing two example.
Ex. 1
from([1, 2, 3, 4]).pipe(
tap((data) => console.log('Before find', data)),
find((data) => data > 5),
tap((data) => console.log('After find', data))
)
.subscribe({
next: console.log,
error: console.error,
complete: () => console.log('Completed'),
});
Output:
Before find 1
Before find 2
Before find 3
Before find 4
After find undefined
undefined
Completed
Ex. 2
<button id="btnFind">Find</button>
const btnFind = document.getElementById('btnFind');
let count: number = 0;
fromEvent(btnFind, 'click')
.pipe(
tap(() => count ),
// takeUntil(timer(5000)),
tap((count) => console.log('Before find', count)),
find(() => count > 4),
tap((count) => console.log('After find', count))
)
.subscribe({
next: (e) => console.log(e),
error: console.error,
complete: () => console.log('Completed'),
});
In 2nd example It will emit after 5th click or if you uncomment takeUntil
then after 5 seconds
CodePudding user response:
If your predicate returns false that means there's no value that matches your condition and the 'find' operator simply will not return any value in this case.
check official rxjs doc for more: https://rxjs.dev/api/operators/find