# Higher-order Function Operator

## Higher-order Functions

Let's quickly recap what a higher-order function is, and take note of the higher-order Observable operators in RxJS.

To quote wikipedia:

A higher-order function is a function that does at least one of the following:

• takes one or more functions as arguments (i.e. procedural parameters),
• returns a function as its result.

Let's take a look at an example of a higher-order function in JavaScript. In this example we'll use a higher-order function in order to calculate values.

``````type Operation = (a: number, b: number) => number;

const add: Operation = (a: number, b: number) => a + b;
const subtract: Operation = (a: number, b: number) => a - b;

const calculator = (start = 0) => (operation: Operation, operand: number) =>
operation(start, operand);

console.log(sum);

sum = calculator(5)(subtract, 4);
console.log(sum);
``````

Let's go through the code example above that uses a higher-order function:

• First, we declare a new `Operation` type. An `Operation` is a function that accepts two `number` value and returns a number.
• Then, we define two `Operation` functions: `add()` and `subtract()`.
• The `calculator` is a higher-order function that has a `start` value and returns a function, which accepts an `Operation` function and the `operand` number value. The "inner" function invokes the `operation()` function using the `start` and `operand` values.
• Now, let's look at two implementation that use the `calculator()` higher-order function. First, we use the `add()` function, and then we use the `subtract()` function.

## Higher-order Observables

Similar to a higher-order function, a higher-order Observable is an Observable that emits one or more Observables.

Let's look at a simple implementation of a higher-order Observable:

``````import { Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';

const higherOrderObservable = new Observable((observer) => {
let i = 0;
const add = new Observable((_observer) => _observer.next(i++ * 10));
const handle = window.setInterval(() => observer.next(add), 1000);
return () => window.clearInterval(handle);
});

higherOrderObservable
.pipe(
switchMap((observable: Observable<number>) =>
observable.pipe(tap(console.log))
)
)
.subscribe();
``````

In this example we are creating a higher-order Observable that emits an Observable:

• First we create a new `Observable` instance. Let's refer to this Observable as the "outer" Observable.
• Then, we declare `i` to start with `0`.
• The `add` constant is a new Observable that emits a next notification that multiplies the incremented `i` value by `10`. Let's refer to this Observable as the "inner" Observable.
• We use `window.setInterval()` to emit to the Observer the inner `add` Observable every 1000 milliseconds.
• When the outer Observable is unsubscribed from the teardown function is invoked, which clears the interval.
• Finally, we subscribe to the outer Observable. The `switchMap()` operator receives an Observable as the next notification. The `switchMap()` subscribes to the inner Observable and maps to the next notification emitted by the inner Observable.

## Higher-order Function as Operator

Having reviewed both higher-order functions and Observables, let's bring these two concepts together to create a new operator using a higher-order function.

The goal of the operator is to calculate the characters entered into a textarea per second.

``````import { fromEvent, Observable, from } from 'rxjs';
import { count, filter, map, mergeMap, windowTime } from 'rxjs/operators';

function characterCount(timeout = 1000) {
return (source: Observable<string>) =>
source.pipe(
windowTime(timeout),
mergeMap((value) =>
from(value).pipe(
count(),
filter((count) => count > 0)
)
)
);
}

const input = document.getElementById('input') as HTMLTextAreaElement;
const output = document.getElementById('output') as HTMLInputElement;
fromEvent(input, 'keyup')
.pipe(
map(() => input.value),
characterCount()
)
.subscribe({
error: console.error,
next: (count) => (output.value = count.toString()),
complete: () => console.log('complete')
});
``````

Let's review our `characterCount` operator.

• First, we can see right away that we have created a higher-order function. The `characterCount` function accepts an optional `timeout` argument and returns a new function.
• The returned function accepts the `source` Observable.
• We are using the `windowTime` operator to slice up the `source` Observable based on the `timeout` and emit a new Observable.
• The `mergeMap()` operator's source Observable is the string of characters entered within the window of the `timeout`. We use the `from()` operator to create a new Observable that emits for each character, and then `count()` the number of next notification, filtering out those counts that are not greater than `0`.