# 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);
let sum = calculator(5)(add, 4);
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`

.