RxJS Tip: Creation Function: fromEvent()
Published: 2020-11-17 19:36:19

The RxJS `fromEvent` is a creation function that emits events.

# How Does It Work?
The `fromEvent` creation function takes in an event target object and event type string, creates an Observable, and emits the specified events as they occur.

It works with any document object model (DOM) element, such as buttons, input elements, and the document itself.

Find the list of valid event types in the [Mozilla docs here](https://developer.mozilla.org/en-US/docs/Web/API/Element#Events). 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ju4hnw248rnl72yzk8of.jpg)

The above example watches for `click` events on the `myInput` element. 

Each `click` event is emitted and logged to the console.

# How About Some Examples?
This example watches for `click` events anywhere on the document (web page). When a click event is emitted, it's x and y coordinates are logged.
```typescript
// Click event on the document page
fromEvent(document, 'click').subscribe(
    (x: MouseEvent) => console.log(`x: ${x.x}, y: ${x.y}`)
);
```

The following example first locates the element with an id of `name`. It then watches for `keyup` events in the `name` element. Each `keyup` event is emitted and it's key code is logged to the console.
```typescript
// Keyup event on an input element
var input = document.getElementById('name');
fromEvent(input, 'keyup').subscribe(
    (x: KeyboardEvent) => console.log(`key: ${x.code}`)
);
```

Here is a more complete Angular example. In the template, it uses a template reference variable (filterInput) on an input element.

**Template**
```html
<input type='text' #filterInput/>
```

In the component, it uses the `ViewChild` decorator to locate the element using the template reference variable (filterInput). In the `ngAfterViewInit` lifecycle hook method, it uses the `fromEvent` creation function, passing in the found element and the desired event (keyup).

**Component**
```typescript
import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
import { fromEvent } from 'rxjs';
@Component({
  templateUrl: './product-list.component.html'})
export class ProductListComponent implements AfterViewInit {
   @ViewChild('filterInput') filterElementRef: ElementRef;

   ngAfterViewInit(): void {
    fromEvent(this.filterElementRef.nativeElement, 'keyup').subscribe(
      (x: KeyboardEvent) => console.log(`key: ${x.code}`)
    );
  }
}
```

>Note that there are often more "Angular" ways to accomplish event handling using event binding. Consider using event binding as a first choice and only use `fromEvent` if event binding doesn't provide the features you require.

# What Are Some Common Uses?
Here are some common uses of the `fromEvent` creation function.

Tracking and responding to click events.
```typescript
fromEvent(document, 'click')
```

Tracking and responding to keyboard events.
```typescript
fromEvent(input, 'keyup')
```

Tracking and responding to clipboard events.
```typescript
fromEvent(document, 'paste')
```

# Where's the Code?
Here is a [link to sample code](https://stackblitz.com/edit/rxjs-fromevent-deborahk) demonstrating the `fromEvent` creation function. Feel free to fork it and try it out.

# What About the Marble Diagram?
This is the `fromEvent` creation function shown on a marble diagram:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/s65p90dnrhnmidmgdpl1.jpg)
Thanks to @michael_hladky for this marble diagram.

Do you have another common use of `fromEvent`? If so, please leave a comment.

Enjoy!