https://github.com/re-quant/rxjs-awaitable-observables
๐งจ This package makes async/await working with Observables without .toPromise() ๐ฅ
https://github.com/re-quant/rxjs-awaitable-observables
angular async-await nestjs promise rxjs ts typescript
Last synced: about 2 months ago
JSON representation
๐งจ This package makes async/await working with Observables without .toPromise() ๐ฅ
- Host: GitHub
- URL: https://github.com/re-quant/rxjs-awaitable-observables
- Owner: Re-Quant
- License: gpl-3.0
- Created: 2020-06-16T02:16:52.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2023-03-05T00:36:29.000Z (about 2 years ago)
- Last Synced: 2024-04-25T21:44:44.599Z (about 1 year ago)
- Topics: angular, async-await, nestjs, promise, rxjs, ts, typescript
- Language: JavaScript
- Homepage:
- Size: 938 KB
- Stars: 2
- Watchers: 2
- Forks: 0
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# RxJS Awaitable Observables
๐งจ ย ย ๐ฅ ย ย ๐ช ย ย Use async/await with any RxJS stream and be happy ย ย โ ย ย ๐จโ๐ป ย ย ๐
Zero third-party dependencies
ย
Notice: If you have any propositions feel free to make an issue or create a pull request.

## Installation
### 1. Install the package
`yarn add @z-brain/rxjs-awaitable-observables`
or
`npm i -s @z-brain/rxjs-awaitable-observables`### 2. Add the import line of the package to your entry .ts files
Your `main.ts`:
```typescript
import '@z-brain/rxjs-awaitable-observables';
```That is all ๐ย Feel free to use async/await with observables ๐
**Detailed description:**
* In case of Angular project it can be `main.ts`
* In case of a server project it is the entry file of your server app (`index.ts` or `server.ts` in most cases)### 3. Configure you testing framework
If you are going to use async/await with observables in any kind of your tests (unit / e2e) there are two ways to do it:
1. Add a setup file with the import to you testing framework. In case of `Jest` it can be done via `setupFiles` or `setupFilesAfterEnv`. **(recommended)**
```javascript
// jest.config.js
module.exports = {
...
setupFiles: [ './jest.setup.ts' ],
...
};
// jest.setup.ts
import '@z-brain/rxjs-awaitable-observables';
```
2. Or you can manually import the package to each of your test **(unrecommended)**## Usage examples
**1. Simple example: async/await works with completed observables**
```typescript
const value$ = $$.of(123);
const value = await value$;
expect(value).toBe(123);
```**2. Take the first value in the stream**
```typescript
const value$: Observable = $$.of(111, 222, 333);
const value = await value$;
expect(value).toBe(111);
```**3. Takes the last value of a completed stream**
```typescript
const value$: Observable = $$.of(111, 222, 333);
const value = await value$.pipe($.last());
expect(value).toBe(333);
```**4. Take the initial value of `Subject` + `.startWith()`**
```typescript
const newValues$: Observable = new Subject();
const value$ = newValues$.pipe($.startWith(123));const value = await value$;
expect(value).toBe(123);
```**5. Take the first value of `ReplaySubject`**
```typescript
const value$ = new ReplaySubject(2);
value$.next(111);
value$.next(222);
value$.next(333);
value$.next(444);const value = await value$;
expect(value).toBe(333);
```**6. Error handling using try/catch**
```typescript
const MSG = 'Something went wrong';
const err$ = $$.throwError(new Error(MSG));try {
await err$;
} catch (e) {
expect(e.message).toMatch(MSG);
}
```**7. throw an EmptyError on completing observable without a message**
```typescript
const emptyStream$ = $$.EMPTY;try {
await emptyStream$;
} catch (e) {
expect(e).toBeInstanceOf(EmptyError);
}
```**8. Manually .then() call (Promises integration)**
```typescript
const value$: Observable = $$.of(123);const promise = Promise.resolve(10)
.then(multiplier => value$.then(v => v * multiplier));return expect(promise).resolves.toBe(1230);
```## How does it work?
* This package patches `Observables`'s prototype and adds `.then()` method to make all `Observable`s and its children work with `async`/`await` as is without the necessary to call `.toPromise()`
* Yes, the package patches .prototype of another package (RxJS).
In theory, it can be dangerous. However, this package does it enough carefully.
We already saw some successful examples of patching .prototype even build-in functions. (Zone.js for example)
I suggest don't afraid and make our daily work easier and our code more beautiful.**100% test coverage**:
```
async/await tests
โ async/await should work with completed observables
โ Should take the first value in the stream
โ Should take the last value of a completed stream
โ Should take the current value of BehaviorSubject
โ Should take the initial value of Subject + .startWith()
โ Should take the first value of ReplaySubject
โ try/catch should handle an error from the stream via async/await
โ Should throw an EmptyError on completing observable without message
Check integration with Promises
โ Should work with manually .then() call
โ Empty .then() call should just return a promise with the value without any errors
โ In case of error in the stream empty .then() call should do nothing and return rejected promise with the error```
## Development notes
### Quick Start
```bash
cd /code/z-brain
git clone [email protected]:z-brain/rxjs-awaitable-observables.git
cd rxjs-awaitable-observables
yarn install
```### How to use NodeJS version from the `.nvmrc`
1. Install NVM
2. Use `.nvmrc` file one of the next ways:* Execute `nvm use` in the project root directory
* Install [NVM Loader](https://github.com/korniychuk/ankor-shell) and your .nvmrc will be loaded automatically when you open the terminal.
### How to make a build
`npm run build`
### How to run lint
* Just show problems `npm run lint`
* Fix problems if it is possible `npm run lint:fix`### How to run tests
* All tests
`npm run test`
`npm run test:watch`
* Specific tests`npm run test -- src/my.spec.ts`
`npm run test:watch -- src/my.spec.ts`### How to build and publish NPM package
*NPM Token:* `3240...1349`
CI configuration details here: [.github/workflows/npmpublish.yml](.github/workflows/npmpublish.yml)
```bash
npm run pre-push
&& npm version patch -m 'Update package version version to %s'
&& npm run gen-public-package.json
&& cp README.md dist/
&& npm publish dist --access public
&& git push --no-verify && git push --tags --no-verify
```### How to build package to local installation
1. `yarn run build:local`
2. Then you can install a local package build from path `file:.../rxjs-awaitable-observables/dist`.## Author
| [
Anton Korniychuk](https://korniychuk.pro) |
| :---: |