diff --git a/modules/schematics/src/effect/files/__name@dasherize@if-flat__/__name@dasherize__.effects.ts.template b/modules/schematics/src/effect/files/__name@dasherize@if-flat__/__name@dasherize__.effects.ts.template index 09e7ebfcc3..3214983e36 100644 --- a/modules/schematics/src/effect/files/__name@dasherize@if-flat__/__name@dasherize__.effects.ts.template +++ b/modules/schematics/src/effect/files/__name@dasherize@if-flat__/__name@dasherize__.effects.ts.template @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { Actions, Effect<% if (feature) { %>, ofType<% } %> } from '@ngrx/effects'; +import { Actions, <%= effectMethod %><% if (feature) { %>, ofType<% } %> } from '@ngrx/effects'; <% if (feature && api) { %>import { catchError, map, concatMap } from 'rxjs/operators'; import { EMPTY, of } from 'rxjs'; import { Load<%= classify(name) %>sFailure, Load<%= classify(name) %>sSuccess, <%= classify(name) %>ActionTypes, <%= classify(name) %>Actions } from '<%= featurePath(group, flat, "actions", dasherize(name)) %><%= dasherize(name) %>.actions'; @@ -12,8 +12,7 @@ import { <%= classify(name) %>ActionTypes, <%= classify(name) %>Actions } from ' @Injectable() export class <%= classify(name) %>Effects { <% if (feature && api) { %> - @Effect() - load<%= classify(name) %>s$ = this.actions$.pipe( + <%= effectStart %> ofType(<%= classify(name) %>ActionTypes.Load<%= classify(name) %>s), concatMap(() => /** An EMPTY observable only emits completion. Replace with your own observable API request */ @@ -21,15 +20,17 @@ export class <%= classify(name) %>Effects { map(data => new Load<%= classify(name) %>sSuccess({ data })), catchError(error => of(new Load<%= classify(name) %>sFailure({ error })))) ) - );<% } %> + <%= effectEnd %> +<% } %> + <% if (feature && !api) { %> - @Effect() - load<%= classify(name) %>s$ = this.actions$.pipe( + <%= effectStart %> ofType(<%= classify(name) %>ActionTypes.Load<%= classify(name) %>s), /** An EMPTY observable only emits completion. Replace with your own observable API request */ concatMap(() => EMPTY) - ); + <%= effectEnd %> <% } %> + <% if (feature) { %> constructor(private actions$: Actions<<%= classify(name) %>Actions>) {} <% } else { %> diff --git a/modules/schematics/src/effect/index.spec.ts b/modules/schematics/src/effect/index.spec.ts index 909cae69fe..b851bda01d 100644 --- a/modules/schematics/src/effect/index.spec.ts +++ b/modules/schematics/src/effect/index.spec.ts @@ -27,6 +27,7 @@ describe('Effect Schematic', () => { feature: false, root: false, group: false, + effectCreators: false, }; const projectPath = getTestProjectPath(); @@ -316,4 +317,42 @@ describe('Effect Schematic', () => { /constructor\(private actions\$: Actions\) {}/ ); }); + + it('should create an effect using creator function', () => { + const options = { ...defaultOptions, effectCreators: true, feature: true }; + + const tree = schematicRunner.runSchematic('effect', options, appTree); + const content = tree.readContent( + `${projectPath}/src/app/foo/foo.effects.ts` + ); + expect(content).toMatch( + /import { Actions, createEffect, ofType } from '@ngrx\/effects';/ + ); + expect(content).not.toMatch(/@Effect\(\)/); + expect(content).toMatch( + /loadFoos\$ = createEffect\(\(\) => this.actions\$.pipe\(/ + ); + }); + + it('should create an api effect using creator function', () => { + const options = { + ...defaultOptions, + effectCreators: true, + api: true, + feature: true, + }; + + const tree = schematicRunner.runSchematic('effect', options, appTree); + const content = tree.readContent( + `${projectPath}/src/app/foo/foo.effects.ts` + ); + + expect(content).toMatch( + /import { Actions, createEffect, ofType } from '@ngrx\/effects';/ + ); + expect(content).not.toMatch(/@Effect\(\)/); + expect(content).toMatch( + /loadFoos\$ = createEffect\(\(\) => this.actions\$.pipe\(/ + ); + }); }); diff --git a/modules/schematics/src/effect/index.ts b/modules/schematics/src/effect/index.ts index 6ac96571a5..747cd3a2f0 100644 --- a/modules/schematics/src/effect/index.ts +++ b/modules/schematics/src/effect/index.ts @@ -93,6 +93,21 @@ function addImportToNgModule(options: EffectOptions): Rule { }; } +function getEffectMethod(effectCreators?: boolean) { + return effectCreators ? 'createEffect' : 'Effect'; +} + +function getEffectStart(name: string, effectCreators?: boolean): string { + const effectName = stringUtils.classify(name); + return effectCreators + ? `load${effectName}s$ = createEffect(() => this.actions$.pipe(` + : '@Effect()\n' + ` load${effectName}s$ = this.actions$.pipe(`; +} + +function getEffectEnd(effectCreators?: boolean) { + return effectCreators ? '));' : ');'; +} + export default function(options: EffectOptions): Rule { return (host: Tree, context: SchematicContext) => { options.path = getProjectPath(host, options); @@ -116,6 +131,9 @@ export default function(options: EffectOptions): Rule { options.flat ? '' : s, options.group ? 'effects' : '' ), + effectMethod: getEffectMethod(options.effectCreators), + effectStart: getEffectStart(options.name, options.effectCreators), + effectEnd: getEffectEnd(options.effectCreators), ...(options as object), } as any), move(parsedPath.path), diff --git a/modules/schematics/src/effect/schema.json b/modules/schematics/src/effect/schema.json index 7d29ab270d..afde9e7136 100644 --- a/modules/schematics/src/effect/schema.json +++ b/modules/schematics/src/effect/schema.json @@ -63,6 +63,12 @@ "description": "Specifies if effect has api success and failure actions wired up", "aliases": ["a"] + }, + "effectCreators": { + "type": "boolean", + "default": false, + "description": "Specifies whether to use the effect creators function", + "aliases": ["ec"] } }, "required": [] diff --git a/modules/schematics/src/effect/schema.ts b/modules/schematics/src/effect/schema.ts index 96b82a8e1b..7fcde3167c 100644 --- a/modules/schematics/src/effect/schema.ts +++ b/modules/schematics/src/effect/schema.ts @@ -48,4 +48,9 @@ export interface Schema { * Specifies if effect has api success and failure actions wired up */ api?: boolean; + + /** + * Specifies if the effect creation uses 'createEffect' + */ + effectCreators?: boolean; } diff --git a/modules/schematics/src/feature/schema.json b/modules/schematics/src/feature/schema.json index f39099fbec..11b7d7be1f 100644 --- a/modules/schematics/src/feature/schema.json +++ b/modules/schematics/src/feature/schema.json @@ -56,6 +56,13 @@ "description": "Specifies if api success and failure actions, reducer, and effects should be generated as part of this feature.", "aliases": ["a"] + }, + "creators": { + "type": "boolean", + "default": false, + "description": + "Specifies if the effects and actions be created using creator functions", + "aliases": ["c"] } }, "required": [] diff --git a/modules/schematics/src/feature/schema.ts b/modules/schematics/src/feature/schema.ts index 08ac475cb2..c01e13378f 100644 --- a/modules/schematics/src/feature/schema.ts +++ b/modules/schematics/src/feature/schema.ts @@ -44,4 +44,9 @@ export interface Schema { * should be generated as part of this feature. */ api?: boolean; + + /** + * Specifies if the effect creation uses 'createEffect' + */ + effectCreators?: boolean; }