Reputation: 1140
Im trying to create to create a custom rxjs operator. I've already created a few custom operator (e.g. MonoTypeOperatorFunction or just regular Observable, that can take in input as a string, number etc.) and they work fine. My problem is that i want to create an operator that takes in a anonymous function. Like x => x.prop or a predicate.
In this example i want to create an operator that can flatten the elements in an object.
interface B {
bid: number;
}
interface A {
aid: number;
bs: B[];
}
const b1: B = { bid: 1 };
const b2: B = { bid: 2 };
const a1: A = { aid: 1, bs: [b1, b2] };
const a1$ = of(a1);
// I want to combine map and concatMap into a single operator
const result = a1$.pipe(
map(x => x.bs),
concatMap(x => x)
).subscribe(x => console.log(x))
// OUTPUT: {bid:1}, {bid:2}
// what i want
// a1$.pipe(many(x => x.bs))
// How i tried to create an operator
// function many<T>(predicate: (input: T) => boolean) {
// return function<T1>(source: Observable<T1>) {
// return source.pipe(map(predicate),concatMap(x => x));
// };
// }
Upvotes: 1
Views: 873
Reputation: 8022
There's already an operator that combines map and concatMap into a single operator, it's called concatMap
.
pipe(map(somefunc), concatMap(x => x))
is always the same as concatMap(somefunc)
. Which explains why it's called concatMap ;)
Your function:
The function you wrote can be rewritten as follows:
function many<T>(predicate: (input: T) => boolean) {
return pipe(map(predicate),concatMap(x => x));
}
which is the same as
function many<T>(predicate: (input: T) => boolean) {
return concatMap(predicate);
}
When you look at this, you should be able to see that you're transforming your stream of type T
into a stream of type boolean
. concatMap
can't subscribe to a boolean. You'll need a function of type (input: T) => Observable<R>
. Which is the same type signature that concatMap
already takes.
Upvotes: 1