With knowledge of extending Subscriber
and using source.lift
to connect a source
to a subscriber
, you can now create your own operators by writing functions that return a source.lift
call. This lesson creates a simple "multiply" operator in RxJS.
Instructor: [00:00] Rename this double to multiply, and then let's invoke this with a 3. We need to take the number and return a function. Even though we're not using the number yet, we're still working, because we're invoking this with a number, and then returning this, and it's getting the source from pipe.
[00:22] Let's pass this number down to a double subscriber and I want to rename this to multiply subscriber, and I'll just pass in that number as well. Now, inside of the constructor here, constructor will take that subscriber or destination, whatever we want to call it, and then a number.
[00:42] I call super with the subscriber and then assign a number. Now, I can access this number down in my next call and just pass it right here. Now, this number, if I look at console log, this.number should come through this 3 each time, so three times that number will now be 3, 6, 9, 12, 15.
[01:09] If I just go ahead and duplicate this line and pass in a 4, we'll see now we have a multiply operator that can take any argument. You'll see the 3s, and the 4s, the 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, and the multiples of 3s, and the multiples of 4s.
[01:26] I'm going to go ahead and extract this to a separate file and the file that's next to it called multiply.js. I will export my function. I need to import subscriber. Import subscriber from RxJS. Now, I can just import from my multiply file. Just multiply.
[01:55] I'll clear out these unused imports, and you can see we now have a custom operator importing from another file which I can use anywhere in my project.
This is really neat. It took me a little while to wrap my brain around why the multiply function itself needs to return a function, rather than simply making number
a second argument, after source
. The reason is that what you pass into pipe
needs to be a function that just takes the source
argument, which is what pipe
supplies. Consequently, if you want to pass additional arguments, you have to write a wrapper function that takes those additional arguments, then returns a function that uses those arguments internally, but just takes the source
argument when called. Then when you call that wrapper function inside the pipe
call, it resolves to what pipe
expects.
If you did want to just make number
a second argument, you could do it this way instead:
observable$.pipe(source => multiply(source, 4)).subscribe(subscriber);
Which amounts to the same thing (but arguably doesn't look as clean).
Fantastic course John, I'm really enjoying it. You should be a Quokka.js affiliate too, I'm now about to purchase a license after seeing it's true potential!