Skip to content

Commit

Permalink
docs: add new Effects lifecycles (#1483)
Browse files Browse the repository at this point in the history
  • Loading branch information
timdeschryver authored and brandonroberts committed Dec 27, 2018
1 parent f067060 commit 7f57f11
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 87 deletions.
16 changes: 7 additions & 9 deletions modules/effects/src/lifecycle_hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@ import { Action } from '@ngrx/store';
*
* ```ts
* class EffectWithIdentifier implements OnIdentifyEffects {
* private effectIdentifier: string;
* constructor(private effectIdentifier: string) {}
*
* ngrxOnIdentifyEffects() {
* return this.effectIdentifier;
* }
* ngrxOnIdentifyEffects() {
* return this.effectIdentifier;
* }
*
* constructor(private effectIdentifier: string) {}
* ```
*/
export interface OnIdentifyEffects {
Expand Down Expand Up @@ -94,10 +93,9 @@ export const onRunEffectsKey: keyof OnRunEffects = 'ngrxOnRunEffects';
*
* ```ts
* class EffectWithInitAction implements OnInitEffects {
*
* ngrxOnInitEffects() {
* return { type: '[EffectWithInitAction] Init' };
* }
* ngrxOnInitEffects() {
* return { type: '[EffectWithInitAction] Init' };
* }
* ```
*/
export interface OnInitEffects {
Expand Down
116 changes: 38 additions & 78 deletions projects/ngrx.io/content/guide/effects/lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,13 @@
After all the root effects have been added, the root effect dispatches a `ROOT_EFFECTS_INIT` action.
You can see this action as a lifecycle hook, which you can use in order to execute some code after all your root effects have been added.

```ts
<code-example header="init.effects.ts">
@Effect()
init$ = this.actions$.pipe(
ofType(ROOT_EFFECTS_INIT),
map(action => ...)
);
```

### UPDATE_EFFECTS

After feature effects are registered, an `UPDATE_EFFECTS` action is dispatched.

```ts
type UpdateEffects = {
type: typeof UPDATE_EFFECTS;
effects: string[];
};
```

For example, when you register your feature module as `EffectsModule.forFeature([SomeEffectsClass, AnotherEffectsClass])`,
it has `SomeEffectsClass` and `AnotherEffectsClass` in an array as its payload.

To dispatch an action when the `SomeEffectsClass` effect has been registered, listen to the `UPDATE_EFFECTS` action and use the `effects` payload to filter out non-important effects.

```ts
@Effect()
init = this.actions.pipe(
ofType<UpdateEffects>(UPDATE_EFFECTS)
filter(action => action.effects.includes('SomeEffectsClass')),
map(action => ...)
);
```
</code-example>

### Non-dispatching Effects

Expand All @@ -46,76 +21,44 @@ Sometimes you don't want effects to dispatch an action, for example when you onl

Usage:

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

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

@Effect({ dispatch: false })
logActions$ = this.actions$.pipe(tap(action => console.log(action)));
}
```

### Initializing effect
</code-example>

You can execute some code that will be executed directly after the effect class is loaded.

```ts
import { Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { defer } from 'rxjs';
import { tap } from 'rxjs/operators';

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

@Effect({ dispatch: false })
init$: Observable<any> = defer(() => of(null)).pipe(
tap(() => console.log('init$'))
);
}
```

If you want to trigger another action, be careful to add this effect at the end.
## Controlling Effects

```ts
import { Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { defer } from 'rxjs';
import { LoginAction, LogoutAction } from './auth.actions';
### OnInitEffects

@Injectable()
export class SomeEffectsClass {
constructor(private actions$: Actions) {}
Implement this interface to dispatch a custom action after the effect has been added.
You can listen to this action in the rest of the application to execute something after the effect is registered.

@Effect({ dispatch: false })
authActions$ = this.actions$.pipe(
ofType<LoginAction | LogoutAction>('LOGIN', 'LOGOUT'),
tap(action => console.log(action))
);
Usage:

// Should be your last effect
@Effect()
init$: Observable<action> = defer(() => {
return of(new LogoutAction());
});
<code-example header="user.effects.ts">
class UserEffects implements OnInitEffects {
ngrxOnInitEffects(): Action {
return { type: '[UserEffects]: Init' };
}
}
```

## Controlling Effects
</code-example>

### OnRunEffects

By default, effects are merged and subscribed to the store. Implement the `OnRunEffects` interface to control the lifecycle of the resolved effects.

Usage:

```ts
<code-example header="user.effects.ts">
import { Injectable } from '@angular/core';
import {
Actions,
Expand All @@ -133,14 +76,14 @@ export class UserEffects implements OnRunEffects {
constructor(private actions$: Actions) {}

@Effect()
updateUser$: Observable<Action> = this.actions$.pipe(
updateUser$: Observable&lt;Action&gt; = this.actions$.pipe(
ofType('UPDATE_USER'),
tap(action => {
console.log(action);
})
);

ngrxOnRunEffects(resolvedEffects$: Observable<EffectNotification>) {
ngrxOnRunEffects(resolvedEffects$: Observable&lt;EffectNotification&gt;) {
return this.actions$.pipe(
ofType('LOGGED_IN'),
exhaustMap(() =>
Expand All @@ -151,4 +94,21 @@ export class UserEffects implements OnRunEffects {
);
}
}
```
</code-example>

### Identify Effects Uniquely

By default, each Effects class is registered once regardless of how many times the Effect class is loaded.
By implementing this interface, you define a unique identifier to register an Effects class instance multiple times.

Usage:

<code-example header="user.effects.ts">
class EffectWithIdentifier implements OnIdentifyEffects {
constructor(private effectIdentifier: string) {}

ngrxOnIdentifyEffects() {
return this.effectIdentifier;
}
}
</code-example>

0 comments on commit 7f57f11

Please sign in to comment.