admin管理员组文章数量:1410717
This is a simplification of a plex case, where some observables in array could be filtered if the values are not valid. The problem is that the filtered observable is not allowing to the other plete the bine. What operator or approach could handle this case allowing the valid data log in the subscription?
// RxJS v6+
import { fromEvent, bineLatest, of } from 'rxjs';
import { mapTo, startWith, scan, tap, map, filter } from 'rxjs/operators';
const userData$ = [
of({ name: 'Joseph', age: 23}),
of({ name: 'Mario', age: 33}),
of({ name: 'Robert', age: 24}),
of({ name: 'Alonso', age: 25})
];
const names = ['Joseph', 'Mario', 'Robert', 'Alonso'];
bineLatest(
names.map((name, i) => {
return userData$[i].pipe(
map(({name, age})=> { return{ name, age: age * 2} }),
filter(({age}) => age < 67),
map(({name, age})=> { return{ name: name.toLocaleUpperCase(), age} }),
)
})
)
.pipe(
tap(console.log),
)
.subscribe();
Sample in stackblitz
If we change the value to 67 all the observables will show the data.
This is a simplification of a plex case, where some observables in array could be filtered if the values are not valid. The problem is that the filtered observable is not allowing to the other plete the bine. What operator or approach could handle this case allowing the valid data log in the subscription?
// RxJS v6+
import { fromEvent, bineLatest, of } from 'rxjs';
import { mapTo, startWith, scan, tap, map, filter } from 'rxjs/operators';
const userData$ = [
of({ name: 'Joseph', age: 23}),
of({ name: 'Mario', age: 33}),
of({ name: 'Robert', age: 24}),
of({ name: 'Alonso', age: 25})
];
const names = ['Joseph', 'Mario', 'Robert', 'Alonso'];
bineLatest(
names.map((name, i) => {
return userData$[i].pipe(
map(({name, age})=> { return{ name, age: age * 2} }),
filter(({age}) => age < 67),
map(({name, age})=> { return{ name: name.toLocaleUpperCase(), age} }),
)
})
)
.pipe(
tap(console.log),
)
.subscribe();
Sample in stackblitz
If we change the value to 67 all the observables will show the data.
Share Improve this question asked Apr 23, 2020 at 5:20 TabaresTabares 4,3455 gold badges44 silver badges52 bronze badges2 Answers
Reset to default 4A typical problem with bineLatest
is that it requires all source Observables to emit at least once so if you use filter
to discard its only value then bineLatest
will never emit anything.
An easy solution is to make sure it always emits with defaultIfEmpty
:
bineLatest(
names.map((name, i) => {
return userData$[i].pipe(
map(({name, age})=> { return { name, age: age * 2} }),
filter(({age}) => age < 66),
map(({name, age})=> { return { name: name.toLocaleUpperCase(), age} }),
defaultIfEmpty(null),
)
})
)
Live demo: https://stackblitz./edit/typescript-rsffbs?file=index.ts
If your real use-case uses other source Observable than of()
that doesn't plete immediatelly you might want to use startWith
instead.
You can replace bineLatest
with from
as bineLatest
won't emit if either one of the item in stream array doesn't emit
const userData$ = [
{ name: 'Joseph', age: 23 },
{ name: 'Mario', age: 33 },
{ name: 'Robert', age: 24 },
{ name: 'Alonso', age: 25 }
];
const names = ['Joseph', 'Mario', 'Robert', 'Alonso'];
from(
userData$
)
.pipe(
map(({ name, age }) => { return { name, age: age * 2 } }),
filter(({ age }) => age < 66),
map(({ name, age }) => { return { name: name.toLocaleUpperCase(), age } }),
tap(console.log),
)
.subscribe();
本文标签: javascriptHow to use combineLatest with filter in certain observableStack Overflow
版权声明:本文标题:javascript - How to use combineLatest with filter in certain observable? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744812317a2626499.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论