Skip to content

Commit

Permalink
add docs
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-okrushko committed May 22, 2019
1 parent 27beb96 commit 8096171
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 2 deletions.
36 changes: 36 additions & 0 deletions projects/ngrx.io/content/guide/effects/lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ init$ = createEffect(() =>
);
</code-example>

## Effect Metadata

### Non-dispatching Effects

Sometimes you don't want effects to dispatch an action, for example when you only want to log or navigate based on an incoming action. But when an effect does not dispatch another action, the browser will crash because the effect is both 'subscribing' to and 'dispatching' the exact same action, causing an infinite loop. To prevent this, add `{ dispatch: false }` to the `createEffect` function as the second argument.
Expand All @@ -36,6 +38,40 @@ export class LogEffects {
}
</code-example>

### Resubscribe on Error

Starting from NgRx V8 when error happens in the effect's main stream it is
reported using Angular's `ErrorHandler` and the source effect is
**automatically** resubscribe (instead of completeling), so it continues to
listen to any new dispatched Actions.

Generally, errors should be handled by users and operators such as `mapToAction`
should make it easier to do. However, for the cases where errors were missed,
this new behavior adds additional safety net.

In some cases where particular RxJS operators are used the new behavior might
produce unexpected results. For example, if the `startWith` operator is within
effect's pipe then it will be triggered again.

To remove resubscriptions add `{resubscribeOnError: false}` to `createEffect`
metadata (second argument).

<code-example header="disable-resubscribe.effects.ts">
import { Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { tap } from 'rxjs/operators';

@Injectable()
export class ErrorFreeEffects {
constructor(private actions$: Actions) {}

disabledResubscriptionsActions$ = createEffect(() =>
this.actions$.pipe(
tap(action => console.log(action))
), { resubscribeOnError: false });
}
</code-example>

## Controlling Effects

### OnInitEffects
Expand Down
8 changes: 6 additions & 2 deletions projects/ngrx.io/content/guide/effects/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,15 @@ describe('My Effects', () => {
});

it('should register someSource$ that dispatches an action', () => {
expect(metadata.someSource$).toEqual({ dispatch: true });
expect(metadata.someSource$).toEqual(
jasmine.objectContaining({ dispatch: true })
);
});

it('should register someOtherSource$ that does not dispatch an action', () => {
expect(metadata.someOtherSource$).toEqual({ dispatch: false });
expect(metadata.someOtherSource$).toEqual(
jasmine.objectContaining({ dispatch: false })
);
});

it('should not register undecoratedSource$', () => {
Expand Down
8 changes: 8 additions & 0 deletions projects/ngrx.io/content/guide/migration/v8.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,14 @@ export const getNews: MemoizedSelector<State, Reaction> = createSelector(
);
```

### @ngrx/effects

#### Resubscribe on Errors

If error occurs (or it flattened into) main effect's pipe then it will be
reported and the effect is resubscribed automatically. In cases when this new behavior is
undesirable, it can be turned off with `{resubscribeOnError: false}` metadata
setting (for each effect individually). [Learn more](/guide/effects/lifecycle#resubscribe-on-error).

### @ngrx/router-store

Expand Down

0 comments on commit 8096171

Please sign in to comment.