@ngry/rx
v16.1.0
Published
RxJS toolkit for Angular development and testing
Downloads
17
Maintainers
Readme
Description
RxJS toolkit for Angular development and testing.
Installation
Using NPM:
npm i @ngry/rx
Using Yarn:
yarn add @ngry/rx
Documentation
Table of contents:
Tasking
toTask
operator
Use toTask
operator to wrap original Observable<T>
into the Observable<TaskState<T>>
.
TaskState
is an immutable structure that indicates async task's pending
/ complete
/ failed
state and holds
task result
or error
.
import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { TaskState, toTask } from '@ngry/rx';
export class ExampleService {
constructor(private http: HttpClient) {
}
get(): Observable<TaskState<Entity>> {
return this.http.get<Entity>('...').pipe(
toTask(),
);
}
}
Then in your component:
import { Observable } from 'rxjs';
import { Component } from '@angular/core';
import { TaskState, takeTaskError, takeTaskResult } from '@ngry/rx';
@Component({
selector: 'x-example',
template: `
<ng-container *ngIf="state$ | async as state">
<p *ngIf="state.isPending()">Loading...</p>
<pre *ngIf="state.isComplete()">{{ state.result | json }}</pre>
</ng-container>
`
})
export class ExampleComponment {
readonly state$ = this.service.get();
readonly result$ = this.state$.pipe(takeTaskResult());
readonly error$ = this.state$.pipe(takeTaskError());
constructor(
private readonly service: ExampleService,
) {}
}
Filtering
ofType
operator
Use ofType
operator to filter values by certain type(s) (it uses instanceof
operator to filter values stream).
export class Load {
constructor(readonly id: number) {
}
}
export class Loaded {
constructor(readonly cart: Cart) {
}
}
export class CartEffects extends EffectsProvider {
constructor(
actions: Actions,
service: CartService,
) {
super([
actions.pipe(
// 👇 Bypass only actions of type Load
ofType(Load),
switchMap(action => service.load(action.id)),
map(cart => new Loaded(cart)),
),
]);
}
}
dispatch
operator
Use dispatch
operator to control whether values must pass through this point of stream or not.
Open mode
from([1, 2, 3])
.pipe(dispatch(true))
.subscribe(console.log);
// Prints 1, 2, 3 then completes
Closed mode
from([1, 2, 3])
.pipe(dispatch(false))
.subscribe(console.log);
// Ignores values, thus prints nothing and completes
Testing
ObservableSpy
ObservableSpy
tracks changes in Observable
like emitted values, completion and failure for further
analysis. Observable
s testing becomes easier.
Test emitted values:
import { from } from 'rxjs';
import { ObservableSpy } from '@ngry/rx';
test('emitted values', () => {
const spy = new ObservableSpy<number>(from([1, 3, 5]));
expect(spy.values).toEqual([1, 3, 5]);
});
Test completion:
import { empty } from 'rxjs';
import { ObservableSpy } from '@ngry/rx';
test('completion', () => {
const spy = new ObservableSpy<number>(empty());
expect(spy.complete).toBe(true);
});
Test error:
import { throwError } from 'rxjs';
import { ObservableSpy } from '@ngry/rx';
test('error', () => {
const spy = new ObservableSpy<number>(throwError('Something went wrong'));
expect(spy.error).toBe('Something went wrong');
});
License
MIT