### Initial Documentation Setup and Serve Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/README.md Install dependencies, perform an initial documentation generation, and start the documentation viewer. ```bash yarn setup yarn start ``` -------------------------------- ### Start rxjs.dev Documentation Site Source: https://github.com/reactivex/rxjs/blob/master/README.md Starts the local development server for the rxjs.dev documentation site. This command requires dependencies to be installed. ```bash yarn workspace rxjs.dev start ``` -------------------------------- ### Install Dependencies and Build Project Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/tools/transforms/rxjs-decision-tree-generator/README.md Installs project dependencies and builds the project. Run this after cloning the repository. ```shell npm i && yarn build ``` -------------------------------- ### Install Dependencies Source: https://github.com/reactivex/rxjs/wiki/Getting-Started After forking and cloning the repository, install the necessary project dependencies using npm. ```bash npm install ``` -------------------------------- ### Install Dependencies Source: https://github.com/reactivex/rxjs/blob/master/README.md Installs all project dependencies using Yarn. This is a prerequisite for development. ```bash yarn install ``` -------------------------------- ### Serve and Sync with Auto-Open Browser Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/README.md Start the serve-and-sync process and automatically open the documentation in the default browser. ```bash npm start -- -o ``` -------------------------------- ### Install RxJS via npm (ES2015) Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/installation.md Use this command to install the latest version of RxJS for ES2015 module systems. ```shell npm install rxjs ``` -------------------------------- ### Install RxJS via npm (All Module Types - npm v3+) Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/installation.md Install RxJS using npm version 3 or later, which supports all module types. ```shell npm install @reactivex/rxjs ``` -------------------------------- ### Observable Marble Syntax Examples Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/testing/marble-testing.md These examples demonstrate the syntax for observable marble diagrams, representing emissions, completion, and errors over virtual time. Use these to define the expected behavior of observables in tests. ```typescript '-' ``` ```typescript '------' ``` ```typescript '|' ``` ```typescript '#' ``` ```typescript '--a--' ``` ```typescript '--a--b--|' ``` ```typescript '--a--b--#' ``` ```typescript '-a-^-b--|' ``` ```typescript '--(abc)-|' ``` ```typescript '-----(a|)' ``` ```typescript 'a 9ms b 9s c|' ``` ```typescript '--a 2.5m b' ``` -------------------------------- ### Multicast Operator Example Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/subject.md Demonstrates how to use the `multicast` operator to share a single Observable execution among multiple Observers. The `connect()` method is called to start the shared execution. ```typescript import { from, Subject, multicast } from 'rxjs'; const source = from([1, 2, 3]); const subject = new Subject(); const multicasted = source.pipe(multicast(subject)); // These are, under the hood, `subject.subscribe({...})`: multicasted.subscribe({ next: (v) => console.log(`observerA: ${v}`) }); multicasted.subscribe({ next: (v) => console.log(`observerB: ${v}`) }); // This is, under the hood, `source.subscribe(subject)`: multicasted.connect(); ``` -------------------------------- ### Install RxJS via npm (All Module Types - npm v2) Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/installation.md Install a specific version of RxJS (7.3.0) using npm version 2. ```shell npm install @reactivex/rxjs@7.3.0 ``` -------------------------------- ### Subscription Marble Syntax Examples Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/testing/marble-testing.md These examples illustrate the subscription marble syntax used with `expectSubscriptions` and `expectObservable`. They define when a subscription begins (`^`) and ends (`!`) within the virtual time of a test. ```typescript '-' ``` ```typescript '------' ``` ```typescript '--^--' ``` ```typescript '--^--!_' ``` ```typescript '500ms ^ 1s !' ``` -------------------------------- ### Install ES6 Shim Typings Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/installation.md Install supplemental typings for CommonJS environments if TypeScript errors like 'Cannot find name 'Promise'' occur. ```shell typings install es6-shim --ambient ``` -------------------------------- ### Run RxJS Test Suite Source: https://github.com/reactivex/rxjs/blob/master/README.md Executes the test suite for the RxJS package. Ensure dependencies are installed before running. ```bash yarn workspace rxjs test ``` -------------------------------- ### Basic Marble Testing Setup Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/testing/marble-testing.md Sets up TestScheduler for synchronous testing of RxJS code. Requires importing TestScheduler and a testing assertion library like chai. ```typescript import { TestScheduler } from 'rxjs/testing'; import { throttleTime } from 'rxjs'; const testScheduler = new TestScheduler((actual, expected) => { // asserting the two objects are equal - required // for TestScheduler assertions to work via your test framework // e.g. using chai. expect(actual).deep.equal(expected); }); // This test runs synchronously. it('generates the stream correctly', () => { testScheduler.run((helpers) => { const { cold, time, expectObservable, expectSubscriptions } = helpers; const e1 = cold(' -a--b--c---|'); const e1subs = ' ^----------!'; const t = time(' ---| '); // t = 3 const expected = '-a-----c---|'; expectObservable(e1.pipe(throttleTime(t))).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(e1subs); }); }); ``` -------------------------------- ### Using globally imported bundle (RxJS v7.2.0+) Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/importing.md Example of using RxJS functions when imported into the global scope. ```javascript const { of, map } = rxjs; of(1, 2, 3).pipe(map((x) => x + '!!!')); // etc ``` -------------------------------- ### Watch for Documentation Changes Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/README.md Start a task that watches for changes in source files and re-processes only the necessary files for documentation generation. ```bash yarn docs-watch ``` -------------------------------- ### Run RxJS Docs Docker Container Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/README.md Start a Docker container for the RxJS documentation app, mapping a host port to the container's port 4200. ```bash docker run -p :4200 rxjs-docs:6.4.1 ``` -------------------------------- ### Using globally imported bundle (RxJS v7.1.0 or older) Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/importing.md Example of using RxJS functions and operators from globally imported bundles for older RxJS versions. ```javascript const { of } = rxjs; const { map } = rxjs.operators; of(1, 2, 3).pipe(map((x) => x + '!!!')); // etc ``` -------------------------------- ### Cold Observable Creation Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/testing/marble-testing.md Creates a cold observable whose subscription starts when the test begins. Use this for observables that only start emitting when subscribed to. ```typescript cold(marbleDiagram: string, values?: object, error?: any) ``` -------------------------------- ### Mocha Browser Runner Setup Source: https://github.com/reactivex/rxjs/blob/master/packages/rxjs/spec/support/mocha-browser-runner.html Initializes the Mocha test scheduler UI and sets up event listeners for test execution. This code is typically found in a test runner HTML file. ```javascript Suite = Mocha.Suite; Test = Mocha.Test; mocha.setup({ui: 'testschedulerui'}); onload = function() { var runner = mocha.run(); var failedTests = []; function logFailure(test, err) { var flattenTitles = function(test) { var titles = []; while (test.parent.title) { titles.push(test.parent.title); test = test.parent; } return titles.reverse(); }; failedTests.push({ name: test.title, result: false, message: err.message, stack: err.stack, titles: flattenTitles(test) }); }; runner.on('end', function() { window.mochaResults = runner.stats; window.mochaResults.reports = failedTests; window.chocoReady = true; }); runner.on('fail', logFailure); }; ``` -------------------------------- ### CDN usage with specific functions (RxJS v7.1.0 or older) Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/importing.md Example of using RxJS functions and operators from CDN with separate imports for older RxJS versions. ```javascript const { range } = rxjs; const { filter, map } = rxjs.operators; range(1, 200) .pipe( filter((x) => x % 2 === 1), map((x) => x + x) ) .subscribe((x) => console.log(x)); ``` -------------------------------- ### Deprecated operator import example Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/importing.md Demonstrates the old and deprecated way of importing operators from 'rxjs/operators'. This method should be avoided. ```typescript import { merge } from 'rxjs/operators'; a$.pipe(merge(b$)).subscribe(); ``` -------------------------------- ### AsyncSubject Example Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/subject.md Demonstrates how AsyncSubject emits only the last value (5) to all observers after completion. Both observers receive the same final value. ```javascript import { AsyncSubject } from 'rxjs'; const subject = new AsyncSubject(); subject.subscribe({ next: (v) => console.log(`observerA: ${v}`), }); subject.next(1); subject.next(2); subject.next(3); subject.next(4); subject.subscribe({ next: (v) => console.log(`observerB: ${v}`), }); subject.next(5); subject.complete(); // Logs: // observerA: 5 // observerB: 5 ``` -------------------------------- ### Using observeOn with asyncScheduler Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/scheduler.md This example demonstrates how to use the `observeOn` operator with `asyncScheduler` to deliver notifications asynchronously. It shows the difference in execution order compared to synchronous delivery. ```typescript import { Observable, observeOn, asyncScheduler } from 'rxjs'; const observable = new Observable((observer) => { observer.next(1); observer.next(2); observer.next(3); observer.complete(); }).pipe( observeOn(asyncScheduler) ); console.log('just before subscribe'); observable.subscribe({ next(x) { console.log('got value ' + x); }, error(err) { console.error('something wrong occurred: ' + err); }, complete() { console.log('done'); }, }); console.log('just after subscribe'); ``` -------------------------------- ### Impure State Management in Plain JavaScript Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/overview.md An example of managing a click counter using a global variable, which can be prone to state issues. ```javascript let count = 0; document.addEventListener('click', () => console.log(`Clicked ${++count} times`)); ``` -------------------------------- ### Run Watch Task for Tests Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/tools/transforms/rxjs-decision-tree-generator/README.md Starts a watch task that automatically re-runs tests when changes are detected in the test files. ```shell yarn test:watch ``` -------------------------------- ### Plain JavaScript Unsubscribe Function Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/observable.md This example demonstrates the core concept of managing resources with a subscribe function that returns an unsubscribe function, similar to how RxJS handles it internally. This is useful for understanding the underlying mechanism. ```javascript function subscribe(subscriber) { const intervalId = setInterval(() => { subscriber.next('hi'); }, 1000); return function unsubscribe() { clearInterval(intervalId); }; } const unsubscribe = subscribe({ next: (x) => console.log(x) }); // Later: unsubscribe(); // dispose the resources ``` -------------------------------- ### Watch for Changes and Rebuild Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/tools/transforms/rxjs-decision-tree-generator/README.md Starts a watch task that automatically rebuilds the JSON tree when changes are detected in the YAML or TypeScript files. ```shell yarn watch ``` -------------------------------- ### Subscribing to an Observable Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/observable.md To receive values from an Observable, you must `subscribe` to it. The `subscribe` method takes an observer object with `next`, `error`, and `complete` handlers. This example demonstrates how to subscribe and log values. ```typescript import { Observable } from 'rxjs'; const observable = new Observable((subscriber) => { subscriber.next(1); subscriber.next(2); subscriber.next(3); setTimeout(() => { subscriber.next(4); subscriber.complete(); }, 1000); }); console.log('just before subscribe'); oble.subscribe({ next(x) { console.log('got value ' + x); }, error(err) { console.error('something wrong occurred: ' + err); }, complete() { console.log('done'); }, }); console.log('just after subscribe'); ``` -------------------------------- ### Flush Virtual Time Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/testing/marble-testing.md Immediately starts virtual time. While `run()` automatically flushes when the callback returns, `flush()` allows for more control, such as flushing multiple times. ```typescript flush() ``` -------------------------------- ### Run Watch Task for Tests with Coverage Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/tools/transforms/rxjs-decision-tree-generator/README.md Starts a watch task that runs the test suite with coverage enabled, automatically re-running tests when changes are detected. ```shell yarn test:watch:coverage ``` -------------------------------- ### CDN usage with specific functions (RxJS v7.2.0+) Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/importing.md Example of using RxJS functions like 'range', 'filter', and 'map' when included via CDN and imported into the global scope. ```javascript const { range, filter, map } = rxjs; range(1, 200) .pipe( filter((x) => x % 2 === 1), map((x) => x + x) ) .subscribe((x) => console.log(x)); ``` -------------------------------- ### Testing Multiple Subscribers with Hot Observable Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/testing/marble-testing.md This example demonstrates testing a hot observable with multiple subscribers that subscribe at different virtual times. It uses `expectObservable` twice with different subscription marbles to verify each subscriber's received emissions. ```typescript testScheduler.run(({ hot, expectObservable }) => { const source = hot('--a--a--a--a--a--a--a--'); const sub1 = ' --^-----------!'; const sub2 = ' ---------^--------!'; const expect1 = ' --a--a--a--a--'; const expect2 = ' -----------a--a--a-'; expectObservable(source, sub1).toBe(expect1); expectObservable(source, sub2).toBe(expect2); }); ``` -------------------------------- ### Marble Testing with Time and Delay Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/testing/marble-testing.md Demonstrates using the `time()` helper to get a duration from a marble diagram and applying it with the `delay` operator. The `expectObservable` assertion verifies the delayed emission. ```typescript testScheduler.run((helpers) => { const { time, cold, expectObservable } = helpers; const source = cold('---a--b--|'); const t = time(' --| '); // --| const expected = ' -----a--b|'; const result = source.pipe(delay(t)); expectObservable(result).toBe(expected); }); ``` -------------------------------- ### RxJS below 7.2 Observable Creation and Operators Source: https://github.com/reactivex/rxjs/blob/master/packages/rxjs/README.md For RxJS versions below 7.2, import Observable creation methods from 'rxjs' and operators from 'rxjs/operators'. This example shows the same functionality as the previous one: creating a range, filtering for odd numbers, and doubling them. ```typescript import { range } from 'rxjs'; import { filter, map } from 'rxjs/operators'; range(1, 200) .pipe( filter((x) => x % 2 === 1), map((x) => x + x) ) .subscribe((x) => console.log(x)); ``` -------------------------------- ### Manually Unsubscribing from an Infinite Stream Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/testing/marble-testing.md This example shows how to manually unsubscribe from an observable that repeats indefinitely using a subscription marble diagram. The `unsub` marble specifies the virtual time at which the subscription should be terminated. ```typescript it('should repeat forever', () => { const testScheduler = createScheduler(); testScheduler.run(({ expectObservable }) => { const foreverStream$ = interval(1).pipe(mapTo('a')); // Omitting this arg may crash the test suite. const unsub = '------!'; expectObservable(foreverStream$, unsub).toBe('-aaaaa'); }); }); ``` -------------------------------- ### RxJS 7.2+ Observable Creation and Operators Source: https://github.com/reactivex/rxjs/blob/master/packages/rxjs/README.md For RxJS versions 7.2 and above, import Observable creation methods like `range` and operators like `filter` and `map` directly from the 'rxjs' package. This example demonstrates creating a range of numbers, filtering for odd values, and doubling them. ```typescript import { range, filter, map } from 'rxjs'; range(1, 200) .pipe( filter((x) => x % 2 === 1), map((x) => x + x) ) .subscribe((x) => console.log(x)); ``` -------------------------------- ### Consolidated Serve and Sync Command Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/README.md Build, watch, and serve the documentation in a single terminal window. ```bash yarn serve-and-sync ``` -------------------------------- ### Build and Serve ServiceWorker Locally Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/README.md Build the RxJS documentation app and serve the distribution files locally to test the ServiceWorker. ```bash yarn build yarn http-server -- dist -p 4200 ``` -------------------------------- ### Build RxJS Docs Docker Image Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/README.md Build a Docker image for the RxJS documentation app. ```bash docker build -t rxjs-docs:6.4.1 . ``` -------------------------------- ### Manual Connection and Subscription Handling Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/subject.md Demonstrates how to manually connect a multicasted Observable using connect() and manage its subscription. This approach requires explicit calls to connect() and unsubscribe() for the shared execution. ```typescript import { interval, Subject, multicast } from 'rxjs'; const source = interval(500); const subject = new Subject(); const multicasted = source.pipe(multicast(subject)); let subscription1, subscription2, subscriptionConnect; subscription1 = multicasted.subscribe({ next: (v) => console.log(`observerA: ${v}`), }); // We should call `connect()` here, because the first // subscriber to `multicasted` is interested in consuming values subscriptionConnect = multicasted.connect(); setTimeout(() => { subscription2 = multicasted.subscribe({ next: (v) => console.log(`observerB: ${v}`), }); }, 600); setTimeout(() => { subscription1.unsubscribe(); }, 1200); // We should unsubscribe the shared Observable execution here, // because `multicasted` would have no more subscribers after this setTimeout(() => { subscription2.unsubscribe(); subscriptionConnect.unsubscribe(); // for the shared Observable execution }, 2000); ``` -------------------------------- ### Create an Observable that completes Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/observable.md An Observable execution produces values for each subscriber. This example shows an Observable that delivers three 'next' notifications and then completes. ```typescript import { Observable } from 'rxjs'; const observable = new Observable(function subscribe(subscriber) { subscriber.next(1); subscriber.next(2); subscriber.next(3); subscriber.complete(); }); ``` -------------------------------- ### Basic Subscription and Unsubscription Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/subscription.md Demonstrates how to subscribe to an Observable and later unsubscribe to cancel the execution and release resources. ```typescript import { interval } from 'rxjs'; const observable = interval(1000); const subscription = observable.subscribe(x => console.log(x)); // Later: // This cancels the ongoing Observable execution which // was started by calling subscribe with an Observer. subscription.unsubscribe(); ``` -------------------------------- ### ReplaySubject with Buffer Size Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/subject.md ReplaySubject records a specified number of past values and replays them to new subscribers. This example buffers the last 3 values. ```typescript import { ReplaySubject } from 'rxjs'; const subject = new ReplaySubject(3); // buffer 3 values for new subscribers subject.subscribe({ next: (v) => console.log(`observerA: ${v}`), }); subject.next(1); subject.next(2); subject.next(3); subject.next(4); subject.subscribe({ next: (v) => console.log(`observerB: ${v}`), }); subject.next(5); // Logs: // observerA: 1 // observerA: 2 // observerA: 3 // observerA: 4 // observerB: 2 // observerB: 3 // observerB: 4 // observerA: 5 // observerB: 5 ``` -------------------------------- ### Run Test Suite with Coverage Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/tools/transforms/rxjs-decision-tree-generator/README.md Executes the test suite and generates a code coverage report. ```shell yarn test:coverage ``` -------------------------------- ### Marble testing with time progression and delays Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/testing/marble-testing.md Illustrates using marble syntax with explicit time progression (e.g., '9ms') and RxJS operators like `concatMap` and `delay` to simulate asynchronous event emissions. ```typescript const input = ' -a-b-c|'; const expected = '-- 9ms a 9ms b 9ms (c|)'; // Depending on your personal preferences you could also // use frame dashes to keep vertical alignment with the input. // const input = ' -a-b-c|'; // const expected = '------- 4ms a 9ms b 9ms (c|)'; // or // const expected = '-----------a 9ms b 9ms (c|)'; const result = cold(input).pipe( concatMap((d) => of(d).pipe( delay(10) )) ); expectObservable(result).toBe(expected); ``` -------------------------------- ### Observable Contract Violation Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/observable.md Observables strictly adhere to the Observable Contract. Any notifications sent after 'complete' or 'error' are ignored, as demonstrated by the 'next(4)' call in this example. ```typescript import { Observable } from 'rxjs'; const observable = new Observable(function subscribe(subscriber) { subscriber.next(1); subscriber.next(2); subscriber.next(3); subscriber.complete(); subscriber.next(4); // Is not delivered because it would violate the contract }); ``` -------------------------------- ### Run Micro Performance Tests Source: https://github.com/reactivex/rxjs/blob/master/CONTRIBUTING.md Execute micro performance tests using Node.js after building the project. These tests focus on operations per second. ```sh yarn build_all node perf/micro ``` -------------------------------- ### Managing Multiple Subscriptions with add() Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/subscription.md Shows how to group multiple subscriptions under a parent subscription using the `add()` method. Calling `unsubscribe()` on the parent will also unsubscribe all its children. ```typescript import { interval } from 'rxjs'; const observable1 = interval(400); const observable2 = interval(300); const subscription = observable1.subscribe(x => console.log('first: ' + x)); const childSubscription = observable2.subscribe(x => console.log('second: ' + x)); subscription.add(childSubscription); setTimeout(() => { // Unsubscribes BOTH subscription and childSubscription subscription.unsubscribe(); }, 1000); ``` -------------------------------- ### Importing from 'rxjs/fetch' Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/importing.md Import fetch API related functionalities like 'fromFetch' from the 'rxjs/fetch' package. ```typescript import { fromFetch } from 'rxjs/fetch'; ``` -------------------------------- ### Creating a Higher-Order Observable Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/higher-order-observables.md This snippet demonstrates the creation of a higher-order Observable where an Observable emits URLs, and each URL is mapped to an HTTP GET request which itself returns an Observable. ```typescript const fileObservable = urlObservable.pipe( map(url => http.get(url)) ); ``` -------------------------------- ### Importing an Operator (RxJS v7.2.0+) Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/importing.md Starting with RxJS v7.2.0, the preferred way to import operators is directly from the 'rxjs' export site. The 'rxjs/operators' export site is deprecated. ```typescript import { map } from 'rxjs'; ``` -------------------------------- ### Run Full Test Suite Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/tools/transforms/rxjs-decision-tree-generator/README.md Executes the complete test suite for the decision tree generator. ```shell yarn test ``` -------------------------------- ### Observable with explicit final observer Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/scheduler.md This code snippet refactors the previous example to explicitly define the `finalObserver`. This helps in understanding the role of the proxy observer introduced by `observeOn`. ```typescript import { Observable, observeOn, asyncScheduler } from 'rxjs'; const observable = new Observable((proxyObserver) => { proxyObserver.next(1); proxyObserver.next(2); proxyObserver.next(3); proxyObserver.complete(); }).pipe( observeOn(asyncScheduler) ); const finalObserver = { next(x) { console.log('got value ' + x); }, error(err) { console.error('something wrong occurred: ' + err); }, complete() { console.log('done'); }, }; console.log('just before subscribe'); observable.subscribe(finalObserver); console.log('just after subscribe'); ``` -------------------------------- ### RxJS Render Parameters Macro Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/tools/transforms/templates/api/lib/paramList.html Macro to render detailed information for each parameter of an RxJS function, including name, type, optional status, default value, and description. ```html {%- macro renderParameters(parameters, containerClass, parameterClass, showType) -%} {%- if parameters.length -%} {% for parameter in parameters %} {% if showType %}{% endif %} {% endfor %} `{$ parameter.name $}` `{$ parameter.type | escape $}` {% marked %} {% if parameter.isOptional or parameter.defaultValue !== undefined %} Optional. Default is `{$ parameter.defaultValue === undefined and 'undefined' or parameter.defaultValue $}`. {% endif %} {% if parameter.description | trim %} {$ parameter.description $} {% elseif not showType and parameter.type %} Type: `{$ parameter.type | escape $}`. {% endif %} {% endmarked %} {%- else -%} There are no parameters. {%- endif -%} {%- endmacro -%} ``` -------------------------------- ### Proxy Observer implementation detail Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/scheduler.md Illustrates the internal mechanism of a proxy observer created by `observeOn`. It shows how `asyncScheduler.schedule` is used to defer the delivery of notifications. ```typescript const proxyObserver = { next(val) { asyncScheduler.schedule( (x) => finalObserver.next(x), 0 /* delay */, val /* will be the x for the function above */ ); }, // ... }; ``` -------------------------------- ### Synchronous function execution Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/observable.md Demonstrates a standard function call and its synchronous execution. ```ts function foo() { console.log('Hello'); return 42; } const x = foo.call(); // same as foo() console.log(x); const y = foo.call(); // same as foo() console.log(y); ``` -------------------------------- ### Importing from 'rxjs/testing' Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/importing.md Import testing utilities like 'TestScheduler' from the 'rxjs/testing' package. ```typescript import { TestScheduler } from 'rxjs/testing'; ``` -------------------------------- ### Run Macro Performance Tests Source: https://github.com/reactivex/rxjs/blob/master/CONTRIBUTING.md Execute macro performance tests after building the project. This involves hosting the root directory with a web server and then running Protractor. ```sh yarn build_all protractor protractor.conf.js ``` -------------------------------- ### Run a Single Micro Performance Test Source: https://github.com/reactivex/rxjs/blob/master/CONTRIBUTING.md Execute a specific micro performance test by providing the test file name as an argument to the Node.js script. ```sh node perf/micro zip ``` -------------------------------- ### Configure Unhandled Error Behavior Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/deprecations/breaking-changes.md Errors during observable subscription setup that occur after an error or completion will now throw in their own call stack. To revert to the previous behavior of calling console.warn, configure the `onUnhandledError` setting. ```typescript import { config } from 'rxjs'; config.onUnhandledError = (err) => console.warn(err); ``` -------------------------------- ### Synchronous Observable subscription with logs Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/observable.md Demonstrates that subscribing to an Observable can also be synchronous, like a function call. ```ts console.log('before'); foo.subscribe((x) => { console.log(x); }); console.log('after'); ``` -------------------------------- ### Importing from 'rxjs/ajax' Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/importing.md Import AJAX functionalities like 'ajax' from the 'rxjs/ajax' package. ```typescript import { ajax } from 'rxjs/ajax'; ``` -------------------------------- ### Using lastValueFrom to get the final emitted value Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/deprecations/to-promise.md Use lastValueFrom to convert an Observable into a Promise that resolves with the last value emitted before completion. This function rejects with an EmptyError if the Observable completes without emitting any values. ```typescript import { interval, take, lastValueFrom } from 'rxjs'; async function execute() { const source$ = interval(2000).pipe(take(10)); const finalNumber = await lastValueFrom(source$); console.log(`The final number is ${finalNumber}`); } execute(); // Expected output: // "The final number is 9" ``` -------------------------------- ### Importing all functions as namespaces (RxJS v7.1.0 or older) Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/importing.md Import core RxJS and operators under separate namespaces for older RxJS versions. ```typescript import * as rxjs from 'rxjs'; import * as operators from 'rxjs'; rxjs.of(1, 2, 3).pipe(operators.map((x) => x + '!!!')); // etc; ``` -------------------------------- ### Recommended Subscribe with Next Callback Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/deprecations/subscribe-arguments.md This snippet demonstrates the recommended RxJS subscribe signature when only the next callback is needed, using an anonymous function. ```typescript import { of } from 'rxjs'; // recommended of([1,2,3]).subscribe((v) => console.info(v)); ``` -------------------------------- ### Using firstValueFrom to get the first emitted value Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/deprecations/to-promise.md Use firstValueFrom to convert an Observable into a Promise that resolves with the first value emitted. It immediately unsubscribes from the source Observable. This function rejects with an EmptyError if the Observable completes without emitting any values. ```typescript import { interval, firstValueFrom } from 'rxjs'; async function execute() { const source$ = interval(2000); const firstNumber = await firstValueFrom(source$); console.log(`The first number is ${firstNumber}`); } execute(); // Expected output: // "The first number is 0" ``` -------------------------------- ### Import RxJS Module Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/tools/transforms/templates/api/includes/info-bar.html Demonstrates how to import a specific RxJS module from the Angular package. Ensure the correct package name and module path are used. ```typescript import { {$ doc.name $} } from ['@angular/{$ doc.moduleDoc.id $}']({$ doc.moduleDoc.path $}); ``` -------------------------------- ### Marble Testing with Animate Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/testing/marble-testing.md Demonstrates using the `animate` helper to control the timing of 'paint' events, aligning them with observable emissions to test animations or frame-dependent logic. ```typescript testScheduler.run((helpers) => { const { animate, cold } = helpers; animate(' ---x---x---x---x'); const requests = cold('-r-------r------'); /* ... */ const expected = ' ---a-------b----'; }); ``` -------------------------------- ### Importing all functions as a namespace (RxJS v7.2.0+) Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/importing.md Import all RxJS functionalities under a single namespace 'rxjs' for convenience. ```typescript import * as rxjs from 'rxjs'; rxjs.of(1, 2, 3).pipe(rxjs.map((x) => x + '!!!')); // etc ``` -------------------------------- ### Replace publish() with share() Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/deprecations/multicasting.md When using publish() with refCount(), use share() instead. Configure share() with resetOnRefCountZero: false to match refCount's behavior. ```typescript import { timer, publish, refCount } from 'rxjs'; // deprecated const tick$ = timer(1_000).pipe( publish(), refCount() ); ``` ```typescript import { timer, share } from 'rxjs'; // suggested refactor const tick$ = timer(1_000).pipe( share({ resetOnError: false, resetOnComplete: false, resetOnRefCountZero: false }) ); ``` -------------------------------- ### Importing from 'rxjs/webSocket' Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/importing.md Import WebSocket functionalities like 'webSocket' from the 'rxjs/webSocket' package. ```typescript import { webSocket } from 'rxjs/webSocket'; ``` -------------------------------- ### RxJS Parameter List Macro Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/tools/transforms/templates/api/lib/paramList.html Macro to render a list of parameters for an RxJS function, including their types and optional status. ```html {% macro paramList(params, truncateLines) -%} {%- if params -%} ({%- for param in params -%} {$ param | escape | truncateCode(truncateLines) $} {%- if not loop.last %}, {% endif %} {%- endfor %}) {%- endif -%} {%- endmacro -%} ``` -------------------------------- ### Create Custom Operator from Scratch Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/guide/operators.md Implement a custom operator from scratch using the Observable constructor for complex logic not achievable by combining existing operators. Ensure all Observer functions (`next`, `error`, `complete`) are implemented and a finalization function is returned for cleanup. ```typescript import { Observable, of } from 'rxjs'; function delay(delayInMillis: number) { return (observable: Observable) => new Observable((subscriber) => { const allTimerIDs = new Set(); let hasCompleted = false; const subscription = observable.subscribe({ next(value) { const timerID = setTimeout(() => { subscriber.next(value); allTimerIDs.delete(timerID); if (hasCompleted && allTimerIDs.size === 0) { subscriber.complete(); } }, delayInMillis); allTimerIDs.add(timerID); }, error(err) { subscriber.error(err); }, complete() { hasCompleted = true; if (allTimerIDs.size === 0) { subscriber.complete(); } }, }); return () => { subscription.unsubscribe(); for (const timerID of allTimerIDs) { clearTimeout(timerID); } }; }); } // Try it out! of(1, 2, 3).pipe(delay(1000)).subscribe(console.log); ``` -------------------------------- ### Recommended Subscribe with Observer Object Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/content/deprecations/subscribe-arguments.md This snippet shows the recommended RxJS subscribe signature using a full Observer object, which includes next, error, and complete callbacks. This approach is preferred for clarity when specifying more than just the next callback. ```typescript import { of } from 'rxjs'; // also recommended of([1,2,3]).subscribe({ next: (v) => console.log(v), error: (e) => console.error(e), complete: () => console.info('complete') }) ``` -------------------------------- ### Save and Load Docker Image Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/README.md Save a Docker image to a tar archive for offline use and load it back. ```bash sudo docker save rxjs-docs:6.4.1 > .tar sudo docker load < .tar ``` -------------------------------- ### Polyfill for Object.assign Source: https://github.com/reactivex/rxjs/blob/master/apps/rxjs.dev/src/index.html Provides a polyfill for `Object.assign` for browsers that do not support it. It fetches the polyfill script synchronously using XHR and appends it to the document head. ```javascript if (!Object.assign) { var polyfillUrl = "https://cdnjs.cloudflare.com/polyfill/v2/polyfill.min.js?features=default,Array.prototype.find&flags=gated&unknown=polyfill"; var xhr = new XMLHttpRequest(); xhr.addEventListener("load", function() { var s = document.createElement('script'); s.type = 'text/javascript'; var code = this.responseText; s.appendChild(document.createTextNode(code)); document.head.appendChild(s); }); xhr.open("GET", polyfillUrl, false); xhr.send(); } ```