{ "id": "guide/practical-observable-usage", "title": "Practical observable usage", "contents": "\n\n\n
\n mode_edit\n
\n\n\n
\n

Practical observable usagelink

\n

Here are some examples of domains in which observables are particularly useful.

\n

Type-ahead suggestionslink

\n

Observables can simplify the implementation of type-ahead suggestions. Typically, a type-ahead has to do a series of separate tasks:

\n\n

Writing this in full JavaScript can be quite involved. With observables, you can use a simple series of RxJS operators:

\n\nimport { fromEvent } from 'rxjs';\nimport { ajax } from 'rxjs/ajax';\nimport { debounceTime, distinctUntilChanged, filter, map, switchMap } from 'rxjs/operators';\n\nconst searchBox = document.getElementById('search-box');\n\nconst typeahead = fromEvent(searchBox, 'input').pipe(\n map((e: KeyboardEvent) => (e.target as HTMLInputElement).value),\n filter(text => text.length > 2),\n debounceTime(10),\n distinctUntilChanged(),\n switchMap(searchTerm => ajax(`/api/endpoint?search=${searchTerm}`))\n);\n\ntypeahead.subscribe(data => {\n // Handle the data from the API\n});\n\n\n\n

Exponential backofflink

\n

Exponential backoff is a technique in which you retry an API after failure, making the time in between retries longer after each consecutive failure, with a maximum number of retries after which the request is considered to have failed. This can be quite complex to implement with promises and other methods of tracking AJAX calls. With observables, it is very easy:

\n\nimport { of, pipe, range, throwError, timer, zip } from 'rxjs';\nimport { ajax } from 'rxjs/ajax';\nimport { map, mergeMap, retryWhen } from 'rxjs/operators';\n\nexport function backoff(maxTries, delay) {\n return pipe(\n retryWhen(attempts =>\n zip(range(1, maxTries + 1), attempts).pipe(\n mergeMap(([i, err]) => (i > maxTries) ? throwError(err) : of(i)),\n map(i => i * i),\n mergeMap(v => timer(v * delay)),\n ),\n ),\n );\n}\n\najax('/api/endpoint')\n .pipe(backoff(3, 250))\n .subscribe(function handleData(data) { /* ... */ });\n\n\n\n \n
\n\n\n" }