or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

actions-filtering.mdadvanced-features.mdeffect-creation.mdindex.mdmodule-setup.mdtesting.md

index.mddocs/

0

# @ngrx/effects

1

2

NgRx Effects is a side effect model for @ngrx/store that provides RxJS-powered effect management for Angular applications. It allows for handling asynchronous operations and external interactions while maintaining separation of concerns between pure state logic and side effects.

3

4

## Package Information

5

6

- **Package Name**: @ngrx/effects

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install @ngrx/effects`

10

11

## Core Imports

12

13

```typescript

14

import {

15

createEffect,

16

Actions,

17

ofType,

18

EffectsModule,

19

provideEffects,

20

mergeEffects,

21

getEffectsMetadata

22

} from "@ngrx/effects";

23

```

24

25

## Basic Usage

26

27

```typescript

28

import { Injectable } from "@angular/core";

29

import { Actions, createEffect, ofType } from "@ngrx/effects";

30

import { map, switchMap } from "rxjs/operators";

31

import { of } from "rxjs";

32

33

@Injectable()

34

export class UserEffects {

35

constructor(private actions$: Actions) {}

36

37

// Class-based effect

38

loadUsers$ = createEffect(() =>

39

this.actions$.pipe(

40

ofType(UserActions.loadUsers),

41

switchMap(() =>

42

this.userService.getUsers().pipe(

43

map(users => UserActions.loadUsersSuccess({ users })),

44

catchError(error => of(UserActions.loadUsersFailure({ error })))

45

)

46

)

47

)

48

);

49

}

50

51

// Functional effect

52

export const loadUsersEffect = createEffect(

53

(actions$ = inject(Actions)) =>

54

actions$.pipe(

55

ofType(UserActions.loadUsers),

56

switchMap(() =>

57

inject(UserService).getUsers().pipe(

58

map(users => UserActions.loadUsersSuccess({ users }))

59

)

60

)

61

),

62

{ functional: true }

63

);

64

```

65

66

## Architecture

67

68

NgRx Effects is built around several key components:

69

70

- **Effect Creation**: `createEffect()` function for defining effects with metadata

71

- **Action Stream**: `Actions` service providing access to all dispatched actions

72

- **Action Filtering**: `ofType()` operator for type-safe action filtering

73

- **Module Integration**: `EffectsModule` for module-based setup, `provideEffects()` for standalone apps

74

- **Lifecycle Management**: Hooks for controlling effect registration and execution

75

- **Error Handling**: Built-in error handling with retry mechanisms

76

- **Testing Support**: Mock providers and utilities for effect testing

77

78

## Capabilities

79

80

### Effect Creation and Management

81

82

Core functionality for creating and managing effects, including both class-based and functional patterns.

83

84

```typescript { .api }

85

function createEffect<

86

C extends EffectConfig & { functional?: false },

87

DT extends DispatchType<C>,

88

OTP,

89

R extends EffectResult<OT>,

90

OT extends ObservableType<DT, OTP>

91

>(

92

source: () => R & ConditionallyDisallowActionCreator<DT, R>,

93

config?: C

94

): R & CreateEffectMetadata;

95

96

function createEffect<Source extends () => Observable<unknown>>(

97

source: Source,

98

config: EffectConfig & { functional: true; dispatch: false }

99

): FunctionalEffect<Source>;

100

101

function createEffect<Source extends () => Observable<Action>>(

102

source: Source & ConditionallyDisallowActionCreator<true, ReturnType<Source>>,

103

config: EffectConfig & { functional: true; dispatch?: true }

104

): FunctionalEffect<Source>;

105

106

function createEffect<

107

Result extends EffectResult<unknown>,

108

Source extends () => Result

109

>(

110

source: Source,

111

config?: EffectConfig

112

): (Source | Result) & CreateEffectMetadata;

113

114

interface EffectConfig {

115

dispatch?: boolean;

116

functional?: boolean;

117

useEffectsErrorHandler?: boolean;

118

}

119

120

type DispatchType<T> = T extends { dispatch: infer U } ? U : true;

121

type ObservableType<T, OriginalType> = T extends false ? OriginalType : Action;

122

type EffectResult<OT> = Observable<OT> | ((...args: any[]) => Observable<OT>);

123

type ConditionallyDisallowActionCreator<DT, Result> = DT extends false

124

? unknown

125

: Result extends EffectResult<infer OT>

126

? OT extends ActionCreator

127

? 'ActionCreator cannot be dispatched. Did you forget to call the action creator function?'

128

: unknown

129

: unknown;

130

131

type FunctionalEffect<

132

Source extends () => Observable<unknown> = () => Observable<unknown>

133

> = Source & FunctionalCreateEffectMetadata;

134

135

interface FunctionalCreateEffectMetadata extends CreateEffectMetadata {

136

'__@ngrx/effects_create__': EffectConfig & { functional: true };

137

}

138

139

interface CreateEffectMetadata {

140

'__@ngrx/effects_create__': EffectConfig;

141

}

142

```

143

144

[Effect Creation and Management](./effect-creation.md)

145

146

### Actions and Filtering

147

148

Action stream management and type-safe action filtering capabilities.

149

150

```typescript { .api }

151

class Actions<V = Action> extends Observable<V> {

152

lift<R>(operator?: Operator<V, R>): Observable<R>;

153

}

154

155

function ofType<E extends Extract<A, { type: T }>, A extends Action = Action, T extends string = A['type']>(

156

...allowedTypes: [T, ...T[]]

157

): OperatorFunction<A, E>;

158

159

function ofType<AC extends ActionCreator<string, Creator>, U extends Action = Action>(

160

...allowedTypes: [AC, ...AC[]]

161

): OperatorFunction<U, ReturnType<AC>>;

162

```

163

164

[Actions and Filtering](./actions-filtering.md)

165

166

### Module Setup and Providers

167

168

Integration with Angular's module system and standalone applications.

169

170

```typescript { .api }

171

class EffectsModule {

172

static forRoot(effects: Type<any>[]): ModuleWithProviders<EffectsRootModule>;

173

static forFeature(effects: Type<any>[]): ModuleWithProviders<EffectsFeatureModule>;

174

}

175

176

function provideEffects(

177

effects: Array<Type<unknown> | Record<string, FunctionalEffect>>

178

): EnvironmentProviders;

179

180

function provideEffects(

181

...effects: Array<Type<unknown> | Record<string, FunctionalEffect>>

182

): EnvironmentProviders;

183

184

function mergeEffects(...effects: Array<Observable<Action> | (() => Observable<Action>)>): () => Observable<Action>;

185

186

function getEffectsMetadata<T extends Record<keyof T, Object>>(instance: T): EffectMetadata<T>[];

187

```

188

189

[Module Setup and Providers](./module-setup.md)

190

191

### Advanced Features

192

193

Lifecycle hooks, error handling, and advanced effect management capabilities.

194

195

```typescript { .api }

196

interface OnIdentifyEffects {

197

ngrxOnIdentifyEffects(): string;

198

}

199

200

interface OnRunEffects {

201

ngrxOnRunEffects(resolvedEffects$: Observable<EffectNotification>): Observable<EffectNotification>;

202

}

203

204

interface OnInitEffects {

205

ngrxOnInitEffects(): Action;

206

}

207

208

type EffectsErrorHandler = <T extends Action>(

209

observable$: Observable<T>,

210

errorHandler: ErrorHandler

211

) => Observable<T>;

212

213

function defaultEffectsErrorHandler<T extends Action>(

214

observable$: Observable<T>,

215

errorHandler: ErrorHandler,

216

retryAttemptLeft: number = 10

217

): Observable<T>;

218

```

219

220

[Advanced Features](./advanced-features.md)

221

222

### Testing Utilities

223

224

Testing support for effects with mock providers and utilities.

225

226

```typescript { .api }

227

function provideMockActions(source: Observable<any>): FactoryProvider;

228

function provideMockActions(factory: () => Observable<any>): FactoryProvider;

229

```

230

231

Import testing utilities:

232

```typescript

233

import { provideMockActions } from "@ngrx/effects/testing";

234

```

235

236

[Testing Utilities](./testing.md)

237

238

## Core Types

239

240

```typescript { .api }

241

interface Action {

242

type: string;

243

}

244

245

interface ActionCreator<T extends string = string, C extends Creator = Creator> {

246

readonly type: T;

247

(...args: any[]): any;

248

}

249

250

interface Creator {

251

(...args: any[]): object;

252

}

253

254

interface EffectNotification {

255

effect: Observable<any> | (() => Observable<any>);

256

propertyName: PropertyKey;

257

sourceName: string | null;

258

sourceInstance: any;

259

notification: ObservableNotification<Action | null | undefined>;

260

}

261

262

interface EffectSources {

263

addEffects(effectSourceInstance: any): void;

264

toActions(): Observable<Action>;

265

}

266

267

class EffectsRunner implements OnDestroy {

268

get isStarted(): boolean;

269

start(): void;

270

ngOnDestroy(): void;

271

}

272

273

interface OnDestroy {

274

ngOnDestroy(): void;

275

}

276

277

interface ObservableNotification<T> {

278

kind: 'N' | 'E' | 'C';

279

value?: T;

280

error?: any;

281

}

282

283

type EffectPropertyKey<T extends Record<keyof T, Object>> = Exclude<

284

keyof T,

285

keyof Object

286

>;

287

288

interface EffectMetadata<T extends Record<keyof T, Object>>

289

extends Required<EffectConfig> {

290

propertyName: EffectPropertyKey<T>;

291

}

292

293

type EffectsMetadata<T extends Record<keyof T, Object>> = {

294

[Key in EffectPropertyKey<T>]?: EffectConfig;

295

};

296

297

interface Type<T = any> {

298

new (...args: any[]): T;

299

}

300

301

interface ModuleWithProviders<T> {

302

ngModule: Type<T>;

303

providers?: any[];

304

}

305

306

interface EnvironmentProviders {

307

ɵproviders: any[];

308

}

309

310

interface FactoryProvider {

311

provide: any;

312

useFactory: (...args: any[]) => any;

313

deps?: any[];

314

}

315

316

interface InjectionToken<T> {

317

toString(): string;

318

}

319

320

interface Observable<T> {

321

pipe(...operations: any[]): Observable<any>;

322

subscribe(...args: any[]): any;

323

}

324

325

interface OperatorFunction<T, R> {

326

(source: Observable<T>): Observable<R>;

327

}

328

329

interface Operator<T, R> {

330

call(subscriber: any, source: Observable<T>): any;

331

}

332

```

333

334

## Constants and Tokens

335

336

```typescript { .api }

337

const ROOT_EFFECTS_INIT: "@ngrx/effects/init";

338

339

function rootEffectsInit(): Action;

340

341

const EFFECTS_ERROR_HANDLER: InjectionToken<EffectsErrorHandler>;

342

const USER_PROVIDED_EFFECTS: InjectionToken<Array<Type<unknown> | InjectionToken<unknown>>[]>;

343

const _ROOT_EFFECTS_GUARD: InjectionToken<void>;

344

const _ROOT_EFFECTS: InjectionToken<[Array<Type<unknown> | Record<string, FunctionalEffect>>]>;

345

const _ROOT_EFFECTS_INSTANCES: InjectionToken<unknown[]>;

346

const _FEATURE_EFFECTS: InjectionToken<Array<Type<unknown> | Record<string, FunctionalEffect>>[]>;

347

const _FEATURE_EFFECTS_INSTANCE_GROUPS: InjectionToken<unknown[][]>;

348

```