diff --git a/angular.json b/angular.json index 782a33c218..f54d03c9cc 100644 --- a/angular.json +++ b/angular.json @@ -757,12 +757,6 @@ { "command": "cpy modules/schematics/src/**/files/**/*.* dist/ --parents" }, - { - "command": "cpy modules/schematics/src/**/creator-files/**/*.* dist/ --parents" - }, - { - "command": "cpy modules/schematics/src/**/common-files/**/*.* dist/ --parents" - }, { "command": "cpy modules/schematics/src/**/integration-files/**/*.* dist/ --parents" }, diff --git a/modules/component-store/schematics-core/utility/ngrx-utils.ts b/modules/component-store/schematics-core/utility/ngrx-utils.ts index 4e8c8d8f6e..cf58124fce 100644 --- a/modules/component-store/schematics-core/utility/ngrx-utils.ts +++ b/modules/component-store/schematics-core/utility/ngrx-utils.ts @@ -269,8 +269,6 @@ export function omit( .reduce((result, key) => Object.assign(result, { [key]: object[key] }), {}); } -export function getPrefix(options: { prefix?: string; creators?: boolean }) { - return options.creators - ? stringUtils.camelize(options.prefix || 'load') - : stringUtils.capitalize(options.prefix || 'load'); +export function getPrefix(options: { prefix?: string }) { + return stringUtils.camelize(options.prefix || 'load'); } diff --git a/modules/component/schematics-core/utility/ngrx-utils.ts b/modules/component/schematics-core/utility/ngrx-utils.ts index 4e8c8d8f6e..cf58124fce 100644 --- a/modules/component/schematics-core/utility/ngrx-utils.ts +++ b/modules/component/schematics-core/utility/ngrx-utils.ts @@ -269,8 +269,6 @@ export function omit( .reduce((result, key) => Object.assign(result, { [key]: object[key] }), {}); } -export function getPrefix(options: { prefix?: string; creators?: boolean }) { - return options.creators - ? stringUtils.camelize(options.prefix || 'load') - : stringUtils.capitalize(options.prefix || 'load'); +export function getPrefix(options: { prefix?: string }) { + return stringUtils.camelize(options.prefix || 'load'); } diff --git a/modules/data/schematics-core/utility/ngrx-utils.ts b/modules/data/schematics-core/utility/ngrx-utils.ts index 4e8c8d8f6e..cf58124fce 100644 --- a/modules/data/schematics-core/utility/ngrx-utils.ts +++ b/modules/data/schematics-core/utility/ngrx-utils.ts @@ -269,8 +269,6 @@ export function omit( .reduce((result, key) => Object.assign(result, { [key]: object[key] }), {}); } -export function getPrefix(options: { prefix?: string; creators?: boolean }) { - return options.creators - ? stringUtils.camelize(options.prefix || 'load') - : stringUtils.capitalize(options.prefix || 'load'); +export function getPrefix(options: { prefix?: string }) { + return stringUtils.camelize(options.prefix || 'load'); } diff --git a/modules/effects/schematics-core/utility/ngrx-utils.ts b/modules/effects/schematics-core/utility/ngrx-utils.ts index 4e8c8d8f6e..cf58124fce 100644 --- a/modules/effects/schematics-core/utility/ngrx-utils.ts +++ b/modules/effects/schematics-core/utility/ngrx-utils.ts @@ -269,8 +269,6 @@ export function omit( .reduce((result, key) => Object.assign(result, { [key]: object[key] }), {}); } -export function getPrefix(options: { prefix?: string; creators?: boolean }) { - return options.creators - ? stringUtils.camelize(options.prefix || 'load') - : stringUtils.capitalize(options.prefix || 'load'); +export function getPrefix(options: { prefix?: string }) { + return stringUtils.camelize(options.prefix || 'load'); } diff --git a/modules/entity/schematics-core/utility/ngrx-utils.ts b/modules/entity/schematics-core/utility/ngrx-utils.ts index 4e8c8d8f6e..cf58124fce 100644 --- a/modules/entity/schematics-core/utility/ngrx-utils.ts +++ b/modules/entity/schematics-core/utility/ngrx-utils.ts @@ -269,8 +269,6 @@ export function omit( .reduce((result, key) => Object.assign(result, { [key]: object[key] }), {}); } -export function getPrefix(options: { prefix?: string; creators?: boolean }) { - return options.creators - ? stringUtils.camelize(options.prefix || 'load') - : stringUtils.capitalize(options.prefix || 'load'); +export function getPrefix(options: { prefix?: string }) { + return stringUtils.camelize(options.prefix || 'load'); } diff --git a/modules/router-store/schematics-core/utility/ngrx-utils.ts b/modules/router-store/schematics-core/utility/ngrx-utils.ts index 4e8c8d8f6e..cf58124fce 100644 --- a/modules/router-store/schematics-core/utility/ngrx-utils.ts +++ b/modules/router-store/schematics-core/utility/ngrx-utils.ts @@ -269,8 +269,6 @@ export function omit( .reduce((result, key) => Object.assign(result, { [key]: object[key] }), {}); } -export function getPrefix(options: { prefix?: string; creators?: boolean }) { - return options.creators - ? stringUtils.camelize(options.prefix || 'load') - : stringUtils.capitalize(options.prefix || 'load'); +export function getPrefix(options: { prefix?: string }) { + return stringUtils.camelize(options.prefix || 'load'); } diff --git a/modules/schematics-core/utility/ngrx-utils.ts b/modules/schematics-core/utility/ngrx-utils.ts index 4e8c8d8f6e..cf58124fce 100644 --- a/modules/schematics-core/utility/ngrx-utils.ts +++ b/modules/schematics-core/utility/ngrx-utils.ts @@ -269,8 +269,6 @@ export function omit( .reduce((result, key) => Object.assign(result, { [key]: object[key] }), {}); } -export function getPrefix(options: { prefix?: string; creators?: boolean }) { - return options.creators - ? stringUtils.camelize(options.prefix || 'load') - : stringUtils.capitalize(options.prefix || 'load'); +export function getPrefix(options: { prefix?: string }) { + return stringUtils.camelize(options.prefix || 'load'); } diff --git a/modules/schematics/schematics-core/utility/ngrx-utils.ts b/modules/schematics/schematics-core/utility/ngrx-utils.ts index 4e8c8d8f6e..cf58124fce 100644 --- a/modules/schematics/schematics-core/utility/ngrx-utils.ts +++ b/modules/schematics/schematics-core/utility/ngrx-utils.ts @@ -269,8 +269,6 @@ export function omit( .reduce((result, key) => Object.assign(result, { [key]: object[key] }), {}); } -export function getPrefix(options: { prefix?: string; creators?: boolean }) { - return options.creators - ? stringUtils.camelize(options.prefix || 'load') - : stringUtils.capitalize(options.prefix || 'load'); +export function getPrefix(options: { prefix?: string }) { + return stringUtils.camelize(options.prefix || 'load'); } diff --git a/modules/schematics/src/action/creator-files/__name@dasherize@if-flat__/__name@dasherize__.actions.spec.ts.template b/modules/schematics/src/action/creator-files/__name@dasherize@if-flat__/__name@dasherize__.actions.spec.ts.template deleted file mode 100644 index b255498ffd..0000000000 --- a/modules/schematics/src/action/creator-files/__name@dasherize@if-flat__/__name@dasherize__.actions.spec.ts.template +++ /dev/null @@ -1,7 +0,0 @@ -import * as from<%= classify(name) %> from './<%= dasherize(name) %>.actions'; - -describe('<%= prefix %><%= classify(name) %>s', () => { - it('should return an action', () => { - expect(from<%= classify(name) %>.<%= prefix %><%= classify(name) %>s().type).toBe('[<%= classify(name) %>] <%= classify(prefix) %> <%= classify(name) %>s'); - }); -}); diff --git a/modules/schematics/src/action/creator-files/__name@dasherize@if-flat__/__name@dasherize__.actions.ts.template b/modules/schematics/src/action/creator-files/__name@dasherize@if-flat__/__name@dasherize__.actions.ts.template deleted file mode 100644 index fefe45376d..0000000000 --- a/modules/schematics/src/action/creator-files/__name@dasherize@if-flat__/__name@dasherize__.actions.ts.template +++ /dev/null @@ -1,15 +0,0 @@ -import { createAction, props } from '@ngrx/store'; - -export const <%= prefix %><%= classify(name) %>s = createAction( - '[<%= classify(name) %>] <%= classify(prefix) %> <%= classify(name) %>s' -); - -<% if (api) { %>export const <%= prefix %><%= classify(name) %>sSuccess = createAction( - '[<%= classify(name) %>] <%= classify(prefix) %> <%= classify(name) %>s Success', - props<{ data: any }>() -);<% } %> - -<% if (api) { %>export const <%= prefix %><%= classify(name) %>sFailure = createAction( - '[<%= classify(name) %>] <%= classify(prefix) %> <%= classify(name) %>s Failure', - props<{ error: any }>() -);<% } %> diff --git a/modules/schematics/src/action/files/__name@dasherize@if-flat__/__name@dasherize__.actions.spec.ts.template b/modules/schematics/src/action/files/__name@dasherize@if-flat__/__name@dasherize__.actions.spec.ts.template deleted file mode 100644 index 5abcf4591a..0000000000 --- a/modules/schematics/src/action/files/__name@dasherize@if-flat__/__name@dasherize__.actions.spec.ts.template +++ /dev/null @@ -1,7 +0,0 @@ -import * as <%= classify(name) %>Actions from './<%= dasherize(name) %>.actions'; - -describe('<%= classify(name) %>', () => { - it('should create an instance', () => { - expect(new <%= classify(name)%>Actions.<%= prefix %><%= classify(name) %>s()).toBeTruthy(); - }); -}); diff --git a/modules/schematics/src/action/files/__name@dasherize@if-flat__/__name@dasherize__.actions.ts.template b/modules/schematics/src/action/files/__name@dasherize@if-flat__/__name@dasherize__.actions.ts.template index 92afc4d7a6..fefe45376d 100644 --- a/modules/schematics/src/action/files/__name@dasherize@if-flat__/__name@dasherize__.actions.ts.template +++ b/modules/schematics/src/action/files/__name@dasherize@if-flat__/__name@dasherize__.actions.ts.template @@ -1,24 +1,15 @@ -import { Action } from '@ngrx/store'; +import { createAction, props } from '@ngrx/store'; -export enum <%= classify(name) %>ActionTypes { - <%= prefix %><%= classify(name) %>s = '[<%= classify(name) %>] <%= prefix %> <%= classify(name) %>s', - <% if (api) { %><%= prefix %><%= classify(name) %>sSuccess = '[<%= classify(name) %>] <%= prefix %> <%= classify(name) %>s Success',<% } %> - <% if (api) { %><%= prefix %><%= classify(name) %>sFailure = '[<%= classify(name) %>] <%= prefix %> <%= classify(name) %>s Failure',<% } %> -} +export const <%= prefix %><%= classify(name) %>s = createAction( + '[<%= classify(name) %>] <%= classify(prefix) %> <%= classify(name) %>s' +); -export class <%= prefix %><%= classify(name) %>s implements Action { - readonly type = <%= classify(name) %>ActionTypes.<%= prefix %><%= classify(name) %>s; -} -<% if (api) { %> -export class <%= prefix %><%= classify(name) %>sSuccess implements Action { - readonly type = <%= classify(name) %>ActionTypes.<%= prefix %><%= classify(name) %>sSuccess; - constructor(public payload: { data: any }) { } -} +<% if (api) { %>export const <%= prefix %><%= classify(name) %>sSuccess = createAction( + '[<%= classify(name) %>] <%= classify(prefix) %> <%= classify(name) %>s Success', + props<{ data: any }>() +);<% } %> -export class <%= prefix %><%= classify(name) %>sFailure implements Action { - readonly type = <%= classify(name) %>ActionTypes.<%= prefix %><%= classify(name) %>sFailure; - constructor(public payload: { error: any }) { } -} -<% } %> -<% if (api) { %>export type <%= classify(name) %>Actions = <%= prefix %><%= classify(name) %>s | <%= prefix %><%= classify(name) %>sSuccess | <%= prefix %><%= classify(name) %>sFailure;<% } %> -<% if (!api) { %>export type <%= classify(name) %>Actions = <%= prefix %><%= classify(name) %>s;<% } %> +<% if (api) { %>export const <%= prefix %><%= classify(name) %>sFailure = createAction( + '[<%= classify(name) %>] <%= classify(prefix) %> <%= classify(name) %>s Failure', + props<{ error: any }>() +);<% } %> diff --git a/modules/schematics/src/action/index.spec.ts b/modules/schematics/src/action/index.spec.ts index 48c01d5bb2..2a72b79a82 100644 --- a/modules/schematics/src/action/index.spec.ts +++ b/modules/schematics/src/action/index.spec.ts @@ -49,8 +49,8 @@ describe('Action Schematic', () => { .toPromise(); const files = tree.files; expect( - files.indexOf(`${specifiedProjectPath}/src/lib/foo.actions.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${specifiedProjectPath}/src/lib/foo.actions.ts`) + ).toBeTruthy(); }); it('should create one file', async () => { @@ -58,11 +58,11 @@ describe('Action Schematic', () => { .runSchematicAsync('action', defaultOptions, appTree) .toPromise(); expect( - tree.files.indexOf(`${projectPath}/src/app/foo.actions.ts`) - ).toBeGreaterThanOrEqual(0); + tree.files.includes(`${projectPath}/src/app/foo.actions.ts`) + ).toBeTruthy(); }); - it('should create two files test files by default', async () => { + it('should not create test files', async () => { const options = { ...defaultOptions, }; @@ -70,134 +70,68 @@ describe('Action Schematic', () => { .runSchematicAsync('action', options, appTree) .toPromise(); expect( - tree.files.indexOf(`${projectPath}/src/app/foo.actions.spec.ts`) - ).toBeGreaterThanOrEqual(0); - expect( - tree.files.indexOf(`${projectPath}/src/app/foo.actions.ts`) - ).toBeGreaterThanOrEqual(0); + tree.files.includes(`${projectPath}/src/app/foo.actions.spec.ts`) + ).toBe(false); }); - it('should not create test files when skipTests is set to true', async () => { + it('should create a const for the action creator', async () => { const options = { ...defaultOptions, - skipTests: true, }; + const tree = await schematicRunner .runSchematicAsync('action', options, appTree) .toPromise(); - expect( - tree.files.indexOf(`${projectPath}/src/app/foo.actions.spec.ts`) - ).toEqual(-1); - expect( - tree.files.indexOf(`${projectPath}/src/app/foo.actions.ts`) - ).toBeGreaterThanOrEqual(0); - }); - - describe('action classes', () => { - const actionClassesDefaultOptions = { ...defaultOptions, creators: false }; - - it('should create an enum named "Foo"', async () => { - const tree = await schematicRunner - .runSchematicAsync('action', actionClassesDefaultOptions, appTree) - .toPromise(); - const fileContent = tree.readContent( - `${projectPath}/src/app/foo.actions.ts` - ); - - expect(fileContent).toMatch(/export enum FooActionTypes/); - }); - - it('should create a class based on the provided name', async () => { - const tree = await schematicRunner - .runSchematicAsync('action', actionClassesDefaultOptions, appTree) - .toPromise(); - const fileContent = tree.readContent( - `${projectPath}/src/app/foo.actions.ts` - ); - - expect(fileContent).toMatch(/export class LoadFoos implements Action/); - }); + const fileContent = tree.readContent( + `${projectPath}/src/app/foo.actions.ts` + ); - it('should create the union type based on the provided name', async () => { - const tree = await schematicRunner - .runSchematicAsync('action', actionClassesDefaultOptions, appTree) - .toPromise(); - const fileContent = tree.readContent( - `${projectPath}/src/app/foo.actions.ts` - ); + expect(fileContent).toMatch(/export const loadFoos = createAction\(/); + expect(fileContent).toMatch(/\[Foo\] Load Foos'/); + }); - expect(fileContent).toMatch(/export type FooActions = LoadFoos/); - }); + it('should create success/error actions when the api flag is set', async () => { + const options = { + ...defaultOptions, + api: true, + }; - it('should create spec class with right imports', async () => { - const options = { ...actionClassesDefaultOptions }; - const tree = await schematicRunner - .runSchematicAsync('action', options, appTree) - .toPromise(); - const fileContent = tree.readContent( - `${projectPath}/src/app/foo.actions.spec.ts` - ); + const tree = await schematicRunner + .runSchematicAsync('action', options, appTree) + .toPromise(); + const fileContent = tree.readContent( + `${projectPath}/src/app/foo.actions.ts` + ); - expect(fileContent).toMatch(/expect\(new FooActions.LoadFoos\(\)\)/); - }); + expect(fileContent).toMatch(/export const loadFoos = createAction\(/); + expect(fileContent).toMatch(/\[Foo\] Load Foos Success/); + expect(fileContent).toMatch(/props<{ data: any }>\(\)/); + expect(fileContent).toMatch(/\[Foo\] Load Foos Failure/); + expect(fileContent).toMatch(/props<{ error: any }>\(\)/); }); - describe('action creators', () => { - const creatorDefaultOptions = { ...defaultOptions }; + it.each(['load', 'delete', 'update'])( + 'should create a action with prefix', + async (prefix) => { + const options = { + ...defaultOptions, + prefix: prefix, + }; - it('should create a const for the action creator', async () => { const tree = await schematicRunner - .runSchematicAsync('action', creatorDefaultOptions, appTree) + .runSchematicAsync('action', options, appTree) .toPromise(); const fileContent = tree.readContent( `${projectPath}/src/app/foo.actions.ts` ); - - expect(fileContent).toMatch(/export const loadFoos = createAction\(/); - expect(fileContent).toMatch(/\[Foo\] Load Foos'/); - }); - - it('should create success/error actions when the api flag is set', async () => { - const tree = await schematicRunner - .runSchematicAsync( - 'action', - { ...creatorDefaultOptions, api: true }, - appTree - ) - .toPromise(); - const fileContent = tree.readContent( - `${projectPath}/src/app/foo.actions.ts` + expect(fileContent).toMatch( + new RegExp(`export const ${prefix}Foos = createAction`) ); - - expect(fileContent).toMatch(/export const loadFoos = createAction\(/); - expect(fileContent).toMatch(/\[Foo\] Load Foos Success/); - expect(fileContent).toMatch(/props<{ data: any }>\(\)/); - expect(fileContent).toMatch(/\[Foo\] Load Foos Failure/); - expect(fileContent).toMatch(/props<{ error: any }>\(\)/); - }); - - it.each(['load', 'delete', 'update'])( - 'should create a action with prefix', - async (prefix) => { - const tree = await schematicRunner - .runSchematicAsync( - 'action', - { ...creatorDefaultOptions, prefix: prefix }, - appTree - ) - .toPromise(); - const fileContent = tree.readContent( - `${projectPath}/src/app/foo.actions.ts` - ); - expect(fileContent).toMatch( - new RegExp(`export const ${prefix}Foos = createAction`) - ); - expect(fileContent).toMatch( - new RegExp(`'\\[Foo] ${capitalize(prefix)} Foos'`) - ); - } - ); - }); + expect(fileContent).toMatch( + new RegExp(`'\\[Foo] ${capitalize(prefix)} Foos'`) + ); + } + ); describe('api', () => { it('should group within an "actions" folder if group is set', async () => { @@ -212,8 +146,8 @@ describe('Action Schematic', () => { ) .toPromise(); expect( - tree.files.indexOf(`${projectPath}/src/app/actions/foo.actions.ts`) - ).toBeGreaterThanOrEqual(0); + tree.files.includes(`${projectPath}/src/app/actions/foo.actions.ts`) + ).toBeTruthy(); }); it('should create a success class based on the provided name, given api', async () => { @@ -255,26 +189,5 @@ describe('Action Schematic', () => { /export const loadFoosFailure = createAction\(\r?\n?\s*'\[Foo\] Load Foos Failure'\r?\n?\s*,/ ); }); - - it('should create the union type with success and failure based on the provided name, given api and creators false', async () => { - const tree = await schematicRunner - .runSchematicAsync( - 'action', - { - ...defaultOptions, - api: true, - creators: false, - }, - appTree - ) - .toPromise(); - const fileContent = tree.readContent( - `${projectPath}/src/app/foo.actions.ts` - ); - - expect(fileContent).toMatch( - /export type FooActions = LoadFoos \| LoadFoosSuccess \| LoadFoosFailure/ - ); - }); }); }); diff --git a/modules/schematics/src/action/index.ts b/modules/schematics/src/action/index.ts index 6a44ed543a..e5e103de00 100644 --- a/modules/schematics/src/action/index.ts +++ b/modules/schematics/src/action/index.ts @@ -4,10 +4,8 @@ import { applyTemplates, branchAndMerge, chain, - filter, mergeWith, move, - noop, url, Tree, SchematicContext, @@ -30,24 +28,18 @@ export default function (options: ActionOptions): Rule { options.name = parsedPath.name; options.path = parsedPath.path; - const templateSource = apply( - url(options.creators ? './creator-files' : './files'), - [ - options.skipTests - ? filter((path) => !path.endsWith('.spec.ts.template')) - : noop(), - applyTemplates({ - ...stringUtils, - 'if-flat': (s: string) => - stringUtils.group( - options.flat ? '' : s, - options.group ? 'actions' : '' - ), - ...options, - }), - move(parsedPath.path), - ] - ); + const templateSource = apply(url('./files'), [ + applyTemplates({ + ...stringUtils, + 'if-flat': (s: string) => + stringUtils.group( + options.flat ? '' : s, + options.group ? 'actions' : '' + ), + ...options, + }), + move(parsedPath.path), + ]); return chain([branchAndMerge(chain([mergeWith(templateSource)]))])( host, diff --git a/modules/schematics/src/action/schema.json b/modules/schematics/src/action/schema.json index 9dfeee9c60..fe995552cd 100644 --- a/modules/schematics/src/action/schema.json +++ b/modules/schematics/src/action/schema.json @@ -30,11 +30,6 @@ "description": "The name of the project.", "aliases": ["p"] }, - "skipTests": { - "type": "boolean", - "description": "When true, does not create test files.", - "default": false - }, "flat": { "type": "boolean", "default": true, @@ -52,13 +47,6 @@ "description": "Specifies if api success and failure actions should be generated.", "aliases": ["a"], "x-prompt": "Should we generate success and failure actions?" - }, - "creators": { - "type": "boolean", - "default": true, - "description": "Specifies whether to use creator functions for handling actions and reducers.", - "aliases": ["c"], - "x-prompt": "Do you want to use the create function?" } }, "required": [] diff --git a/modules/schematics/src/action/schema.ts b/modules/schematics/src/action/schema.ts index dc1c1a9169..ed0fbb398e 100644 --- a/modules/schematics/src/action/schema.ts +++ b/modules/schematics/src/action/schema.ts @@ -19,11 +19,6 @@ export interface Schema { */ project?: string; - /** - * When true, does not create test files. - */ - skipTests?: boolean; - /** * Flag to indicate if a dir is created. */ @@ -40,10 +35,4 @@ export interface Schema { * should be generated. */ api?: boolean; - - /** - * Specifies whether to use creator functions for - * handling actions and reducers. - */ - creators?: boolean; } 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 18cba22b43..c90be6296c 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 @@ -2,28 +2,14 @@ import { Injectable } from '@angular/core'; import { Actions, <%= effectMethod %><% if (feature) { %>, ofType<% } %> } from '@ngrx/effects'; <% if (feature && api) { %>import { catchError, map, concatMap } from 'rxjs/operators'; import { Observable, EMPTY, of } from 'rxjs'; -<% if (!creators) {%>import { <%= prefix %><%= classify(name) %>sFailure, <%= prefix %><%= classify(name) %>sSuccess, <%= classify(name) %>ActionTypes, <%= classify(name) %>Actions } from '<%= featurePath(group, flat, "actions", dasherize(name)) %><%= dasherize(name) %>.actions';<% } %> -<% if (creators) {%>import * as <%= classify(name) %>Actions from '<%= featurePath(group, flat, "actions", dasherize(name)) %><%= dasherize(name) %>.actions';<% } %> -<% } %> +import * as <%= classify(name) %>Actions from '<%= featurePath(group, flat, "actions", dasherize(name)) %><%= dasherize(name) %>.actions';<% } %> <% if (feature && !api) { %>import { concatMap } from 'rxjs/operators'; import { Observable, EMPTY } from 'rxjs'; -<% if (!creators) {%>import { <%= classify(name) %>ActionTypes, <%= classify(name) %>Actions } from '<%= featurePath(group, flat, "actions", dasherize(name)) %><%= dasherize(name) %>.actions';<% } %> -<% if (creators) {%>import * as <%= classify(name) %>Actions from '<%= featurePath(group, flat, "actions", dasherize(name)) %><%= dasherize(name) %>.actions';<% } %> -<% } %> +import * as <%= classify(name) %>Actions from '<%= featurePath(group, flat, "actions", dasherize(name)) %><%= dasherize(name) %>.actions';<% } %> @Injectable() export class <%= classify(name) %>Effects { -<% if (feature && api && !creators) { %> - <%= effectStart %> - ofType(<%= classify(name) %>ActionTypes.<%= prefix %><%= classify(name) %>s), - concatMap(() => - /** An EMPTY observable only emits completion. Replace with your own observable API request */ - EMPTY.pipe( - map(data => new <%= prefix %><%= classify(name) %>sSuccess({ data })), - catchError(error => of(new <%= prefix %><%= classify(name) %>sFailure({ error })))) - ) - <%= effectEnd %> -<% } else if (feature && api && creators) { %> +<% if (feature && api) { %> <%= effectStart %> ofType(<%= classify(name) %>Actions.<%= prefix %><%= classify(name) %>s), concatMap(() => @@ -34,24 +20,12 @@ export class <%= classify(name) %>Effects { ) <%= effectEnd %> <% } %> -<% if (feature && !api && !creators) { %> - <%= effectStart %> - ofType(<%= classify(name) %>ActionTypes.<%= prefix %><%= classify(name) %>s), - /** An EMPTY observable only emits completion. Replace with your own observable API request */ - concatMap(() => EMPTY as Observable<{ type: string }>) - <%= effectEnd %> -<% } else if (feature && !api && creators) { %> +<% if (feature && !api) { %> <%= effectStart %> ofType(<%= classify(name) %>Actions.<%= prefix %><%= classify(name) %>s), /** An EMPTY observable only emits completion. Replace with your own observable API request */ concatMap(() => EMPTY as Observable<{ type: string }>) <%= effectEnd %> <% } %> -<% if (feature && !creators) { %> - constructor(private actions$: Actions<<%= classify(name) %>Actions>) {} -<% } else if (feature && creators) { %> constructor(private actions$: Actions) {} -<% } else { %> - constructor(private actions$: Actions) {} -<% } %> } diff --git a/modules/schematics/src/effect/index.spec.ts b/modules/schematics/src/effect/index.spec.ts index 9411e81ec4..2963d04116 100644 --- a/modules/schematics/src/effect/index.spec.ts +++ b/modules/schematics/src/effect/index.spec.ts @@ -26,7 +26,6 @@ describe('Effect Schematic', () => { feature: false, root: false, group: false, - creators: false, prefix: 'load', }; @@ -304,9 +303,31 @@ describe('Effect Schematic', () => { `${projectPath}/src/app/effects/foo/foo.effects.ts` ); - expect(content).toMatch( - /import \{ FooActionTypes, FooActions } from '\.\.\/\.\.\/actions\/foo\/foo\.actions';/ - ); + expect(content).toMatchInlineSnapshot(` + "import { Injectable } from '@angular/core'; + import { Actions, createEffect, ofType } from '@ngrx/effects'; + + import { concatMap } from 'rxjs/operators'; + import { Observable, EMPTY } from 'rxjs'; + import * as FooActions from '../../actions/foo/foo.actions'; + + @Injectable() + export class FooEffects { + + + loadFoos$ = createEffect(() => { + return this.actions$.pipe( + + ofType(FooActions.loadFoos), + /** An EMPTY observable only emits completion. Replace with your own observable API request */ + concatMap(() => EMPTY as Observable<{ type: string }>) + ); + }); + + constructor(private actions$: Actions) {} + } + " + `); }); it('should create an effect that describes a source of actions within a feature', async () => { @@ -318,24 +339,31 @@ describe('Effect Schematic', () => { const content = tree.readContent( `${projectPath}/src/app/foo/foo.effects.ts` ); - expect(content).toMatch( - /import { Actions, Effect, ofType } from '@ngrx\/effects';/ - ); - expect(content).toMatch(/import { concatMap } from 'rxjs\/operators';/); - expect(content).toMatch(/import { Observable, EMPTY } from 'rxjs';/); - expect(content).toMatch( - /import { FooActionTypes, FooActions } from '\.\/foo.actions';/ - ); - expect(content).toMatch(/export class FooEffects/); - expect(content).toMatch(/loadFoos\$ = this\.actions\$.pipe\(/); - expect(content).toMatch(/ofType\(FooActionTypes\.LoadFoos\)/); - expect(content).toMatch( - /concatMap\(\(\) => EMPTY as Observable<\{ type: string \}>\)/ - ); + expect(content).toMatchInlineSnapshot(` + "import { Injectable } from '@angular/core'; + import { Actions, createEffect, ofType } from '@ngrx/effects'; - expect(content).toMatch( - /constructor\(private actions\$: Actions\) {}/ - ); + import { concatMap } from 'rxjs/operators'; + import { Observable, EMPTY } from 'rxjs'; + import * as FooActions from './foo.actions'; + + @Injectable() + export class FooEffects { + + + loadFoos$ = createEffect(() => { + return this.actions$.pipe( + + ofType(FooActions.loadFoos), + /** An EMPTY observable only emits completion. Replace with your own observable API request */ + concatMap(() => EMPTY as Observable<{ type: string }>) + ); + }); + + constructor(private actions$: Actions) {} + } + " + `); }); it('should create an effect that does not define a source of actions within the root', async () => { @@ -347,16 +375,20 @@ describe('Effect Schematic', () => { const content = tree.readContent( `${projectPath}/src/app/foo/foo.effects.ts` ); - expect(content).toMatch( - /import { Actions, Effect } from '@ngrx\/effects';/ - ); - expect(content).not.toMatch( - /import { FooActionTypes } from '\.\/foo.actions';/ - ); - expect(content).toMatch(/export class FooEffects/); - expect(content).not.toMatch( - /loadFoos\$ = this\.actions\$.pipe\(ofType\(FooActionTypes\.LoadFoos/ - ); + expect(content).toMatchInlineSnapshot(` + "import { Injectable } from '@angular/core'; + import { Actions, createEffect } from '@ngrx/effects'; + + + + @Injectable() + export class FooEffects { + + + constructor(private actions$: Actions) {} + } + " + `); }); it('should create an api effect that describes a source of actions within a feature', async () => { @@ -368,34 +400,40 @@ describe('Effect Schematic', () => { const content = tree.readContent( `${projectPath}/src/app/foo/foo.effects.ts` ); - expect(content).toMatch( - /import { Actions, Effect, ofType } from '@ngrx\/effects';/ - ); - expect(content).toMatch( - /import { catchError, map, concatMap } from 'rxjs\/operators';/ - ); - expect(content).toMatch(/import { Observable, EMPTY, of } from 'rxjs';/); - expect(content).toMatch( - /import { LoadFoosFailure, LoadFoosSuccess, FooActionTypes, FooActions } from '\.\/foo.actions';/ - ); - expect(content).toMatch(/export class FooEffects/); - expect(content).toMatch(/loadFoos\$ = this\.actions\$.pipe\(/); - expect(content).toMatch(/ofType\(FooActionTypes\.LoadFoos\),/); - expect(content).toMatch(/concatMap\(\(\) =>/); - expect(content).toMatch(/EMPTY\.pipe\(/); - expect(content).toMatch(/map\(data => new LoadFoosSuccess\({ data }\)\),/); - expect(content).toMatch( - /catchError\(error => of\(new LoadFoosFailure\({ error }\)\)\)\)/ - ); + expect(content).toMatchInlineSnapshot(` + "import { Injectable } from '@angular/core'; + import { Actions, createEffect, ofType } from '@ngrx/effects'; + import { catchError, map, concatMap } from 'rxjs/operators'; + import { Observable, EMPTY, of } from 'rxjs'; + import * as FooActions from './foo.actions'; - expect(content).toMatch( - /constructor\(private actions\$: Actions\) {}/ - ); + + @Injectable() + export class FooEffects { + + loadFoos$ = createEffect(() => { + return this.actions$.pipe( + + ofType(FooActions.loadFoos), + concatMap(() => + /** An EMPTY observable only emits completion. Replace with your own observable API request */ + EMPTY.pipe( + map(data => FooActions.loadFoosSuccess({ data })), + catchError(error => of(FooActions.loadFoosFailure({ error })))) + ) + ); + }); + + + constructor(private actions$: Actions) {} + } + " + `); }); it('should create an effect using creator function', async () => { - const options = { ...defaultOptions, creators: true, feature: true }; + const options = { ...defaultOptions, feature: true }; const tree = await schematicRunner .runSchematicAsync('effect', options, appTree) @@ -403,36 +441,36 @@ describe('Effect Schematic', () => { 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\(\(\) => {\s* return this.actions\$.pipe\(/ - ); - }); + expect(content).toMatchInlineSnapshot(` + "import { Injectable } from '@angular/core'; + import { Actions, createEffect, ofType } from '@ngrx/effects'; - it('should use action creators when creators is enabled in a feature', async () => { - const options = { ...defaultOptions, creators: true, feature: true }; + import { concatMap } from 'rxjs/operators'; + import { Observable, EMPTY } from 'rxjs'; + import * as FooActions from './foo.actions'; - const tree = await schematicRunner - .runSchematicAsync('effect', options, appTree) - .toPromise(); - const content = tree.readContent( - `${projectPath}/src/app/foo/foo.effects.ts` - ); + @Injectable() + export class FooEffects { - expect(content).toMatch( - /import { Actions, createEffect, ofType } from '@ngrx\/effects';/ - ); - expect(content).toMatch(/import \* as FooActions from '\.\/foo\.actions';/); - expect(content).toMatch(/ofType\(FooActions\.loadFoos\),/); + + loadFoos$ = createEffect(() => { + return this.actions$.pipe( + + ofType(FooActions.loadFoos), + /** An EMPTY observable only emits completion. Replace with your own observable API request */ + concatMap(() => EMPTY as Observable<{ type: string }>) + ); + }); + + constructor(private actions$: Actions) {} + } + " + `); }); it('should create an api effect using creator function', async () => { const options = { ...defaultOptions, - creators: true, api: true, feature: true, }; @@ -444,13 +482,35 @@ describe('Effect Schematic', () => { `${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\(\(\) => {\s* return this.actions\$.pipe\(/ - ); + expect(content).toMatchInlineSnapshot(` + "import { Injectable } from '@angular/core'; + import { Actions, createEffect, ofType } from '@ngrx/effects'; + import { catchError, map, concatMap } from 'rxjs/operators'; + import { Observable, EMPTY, of } from 'rxjs'; + import * as FooActions from './foo.actions'; + + + @Injectable() + export class FooEffects { + + loadFoos$ = createEffect(() => { + return this.actions$.pipe( + + ofType(FooActions.loadFoos), + concatMap(() => + /** An EMPTY observable only emits completion. Replace with your own observable API request */ + EMPTY.pipe( + map(data => FooActions.loadFoosSuccess({ data })), + catchError(error => of(FooActions.loadFoosFailure({ error })))) + ) + ); + }); + + + constructor(private actions$: Actions) {} + } + " + `); }); it('should inject the effect service correctly', async () => { @@ -468,9 +528,9 @@ describe('Effect Schematic', () => { it('should add prefix to the effect', async () => { const options = { ...defaultOptions, - prefix: 'custom', - feature: true, api: true, + feature: true, + prefix: 'custom', }; const tree = await schematicRunner @@ -480,50 +540,34 @@ describe('Effect Schematic', () => { `${projectPath}/src/app/foo/foo.effects.ts` ); - expect(content).toMatch( - /import { CustomFoosFailure, CustomFoosSuccess, FooActionTypes, FooActions } from '\.\/foo.actions';/ - ); + expect(content).toMatchInlineSnapshot(` + "import { Injectable } from '@angular/core'; + import { Actions, createEffect, ofType } from '@ngrx/effects'; + import { catchError, map, concatMap } from 'rxjs/operators'; + import { Observable, EMPTY, of } from 'rxjs'; + import * as FooActions from './foo.actions'; - expect(content).toMatch(/customFoos\$ = this\.actions\$.pipe\(/); - expect(content).toMatch(/ofType\(FooActionTypes\.CustomFoos\),/); - expect(content).toMatch( - /map\(data => new CustomFoosSuccess\({ data }\)\),/ - ); - - expect(content).toMatch( - /catchError\(error => of\(new CustomFoosFailure\({ error }\)\)\)\)/ - ); - }); - - it('should add prefix to the effect using creator function', async () => { - const options = { - ...defaultOptions, - creators: true, - api: true, - feature: true, - prefix: 'custom', - }; + @Injectable() + export class FooEffects { - const tree = await schematicRunner - .runSchematicAsync('effect', options, appTree) - .toPromise(); - const content = tree.readContent( - `${projectPath}/src/app/foo/foo.effects.ts` - ); + customFoos$ = createEffect(() => { + return this.actions$.pipe( - expect(content).toMatch( - /customFoos\$ = createEffect\(\(\) => {\s* return this.actions\$.pipe\(/ - ); - - expect(content).toMatch(/ofType\(FooActions.customFoos\),/); + ofType(FooActions.customFoos), + concatMap(() => + /** An EMPTY observable only emits completion. Replace with your own observable API request */ + EMPTY.pipe( + map(data => FooActions.customFoosSuccess({ data })), + catchError(error => of(FooActions.customFoosFailure({ error })))) + ) + ); + }); - expect(content).toMatch( - /map\(data => FooActions.customFoosSuccess\({ data }\)\),/ - ); - expect(content).toMatch( - /catchError\(error => of\(FooActions.customFoosFailure\({ error }\)\)\)\)/ - ); + constructor(private actions$: Actions) {} + } + " + `); }); }); diff --git a/modules/schematics/src/effect/index.ts b/modules/schematics/src/effect/index.ts index cfc3f19771..a419122903 100644 --- a/modules/schematics/src/effect/index.ts +++ b/modules/schematics/src/effect/index.ts @@ -102,27 +102,14 @@ function addImportToNgModule(options: EffectOptions): Rule { }; } -function getEffectMethod(creators?: boolean) { - return creators ? 'createEffect' : 'Effect'; -} - -function getEffectStart( - name: string, - effectPrefix: string, - creators?: boolean -): string { +function getEffectStart(name: string, effectPrefix: string): string { const effectName = stringUtils.classify(name); const effectMethodPrefix = stringUtils.camelize(effectPrefix); - return creators - ? `${effectMethodPrefix}${effectName}s$ = createEffect(() => {` + - '\n return this.actions$.pipe( \n' - : '@Effect()\n' + - ` ${effectMethodPrefix}${effectName}s$ = this.actions$.pipe(`; -} - -function getEffectEnd(creators?: boolean) { - return creators ? ' );\n' + ' });' : ');'; + return ( + `${effectMethodPrefix}${effectName}s$ = createEffect(() => {` + + '\n return this.actions$.pipe( \n' + ); } export default function (options: EffectOptions): Rule { @@ -151,13 +138,9 @@ export default function (options: EffectOptions): Rule { options.flat ? '' : s, options.group ? 'effects' : '' ), - effectMethod: getEffectMethod(options.creators), - effectStart: getEffectStart( - options.name, - options.prefix, - options.creators - ), - effectEnd: getEffectEnd(options.creators), + effectMethod: 'createEffect', + effectStart: getEffectStart(options.name, options.prefix), + effectEnd: ' );\n' + ' });', ...(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 a865a6ffac..783de9ba49 100644 --- a/modules/schematics/src/effect/schema.json +++ b/modules/schematics/src/effect/schema.json @@ -65,13 +65,6 @@ "aliases": ["a"], "x-prompt": "Should we wire up success and failure actions?" }, - "creators": { - "type": "boolean", - "default": true, - "description": "Specifies whether to use creator functions for handling actions, reducers, and effects.", - "aliases": ["c"], - "x-prompt": "Do you want to use the create function?" - }, "minimal": { "type": "boolean", "default": false, diff --git a/modules/schematics/src/effect/schema.ts b/modules/schematics/src/effect/schema.ts index 0a9aea618e..4b35a61a87 100644 --- a/modules/schematics/src/effect/schema.ts +++ b/modules/schematics/src/effect/schema.ts @@ -49,12 +49,6 @@ export interface Schema { */ api?: boolean; - /** - * Specifies whether to use creator functions for - * handling actions, reducers, and effects. - */ - creators?: boolean; - /** * Setup root effects module without registering initial effects. */ diff --git a/modules/schematics/src/entity/creator-files/__name@dasherize@if-flat__/__name@dasherize@group-actions__.actions.ts.template b/modules/schematics/src/entity/creator-files/__name@dasherize@if-flat__/__name@dasherize@group-actions__.actions.ts.template deleted file mode 100644 index 9d0e837463..0000000000 --- a/modules/schematics/src/entity/creator-files/__name@dasherize@if-flat__/__name@dasherize@group-actions__.actions.ts.template +++ /dev/null @@ -1,53 +0,0 @@ -import { createAction, props } from '@ngrx/store'; -import { Update } from '@ngrx/entity'; - -import { <%= classify(name) %> } from '<%= featurePath(group, flat, "models", dasherize(name)) %><%= dasherize(name) %>.model'; - -export const load<%= classify(name) %>s = createAction( - '[<%= classify(name) %>/API] Load <%= classify(name) %>s', - props<{ <%= camelize(name) %>s: <%= classify(name) %>[] }>() -); - -export const add<%= classify(name) %> = createAction( - '[<%= classify(name) %>/API] Add <%= classify(name) %>', - props<{ <%= camelize(name) %>: <%= classify(name) %> }>() -); - -export const upsert<%= classify(name) %> = createAction( - '[<%= classify(name) %>/API] Upsert <%= classify(name) %>', - props<{ <%= camelize(name) %>: <%= classify(name) %> }>() -); - -export const add<%= classify(name) %>s = createAction( - '[<%= classify(name) %>/API] Add <%= classify(name) %>s', - props<{ <%= camelize(name) %>s: <%= classify(name) %>[] }>() -); - -export const upsert<%= classify(name) %>s = createAction( - '[<%= classify(name) %>/API] Upsert <%= classify(name) %>s', - props<{ <%= camelize(name) %>s: <%= classify(name) %>[] }>() -); - -export const update<%= classify(name) %> = createAction( - '[<%= classify(name) %>/API] Update <%= classify(name) %>', - props<{ <%= camelize(name) %>: Update<<%= classify(name) %>> }>() -); - -export const update<%= classify(name) %>s = createAction( - '[<%= classify(name) %>/API] Update <%= classify(name) %>s', - props<{ <%= camelize(name) %>s: Update<<%= classify(name) %>>[] }>() -); - -export const delete<%= classify(name) %> = createAction( - '[<%= classify(name) %>/API] Delete <%= classify(name) %>', - props<{ id: string }>() -); - -export const delete<%= classify(name) %>s = createAction( - '[<%= classify(name) %>/API] Delete <%= classify(name) %>s', - props<{ ids: string[] }>() -); - -export const clear<%= classify(name) %>s = createAction( - '[<%= classify(name) %>/API] Clear <%= classify(name) %>s' -); diff --git a/modules/schematics/src/entity/creator-files/__name@dasherize@if-flat__/__name@dasherize@group-reducers__.reducer.ts.template b/modules/schematics/src/entity/creator-files/__name@dasherize@if-flat__/__name@dasherize@group-reducers__.reducer.ts.template deleted file mode 100644 index 7439f68efd..0000000000 --- a/modules/schematics/src/entity/creator-files/__name@dasherize@if-flat__/__name@dasherize@group-reducers__.reducer.ts.template +++ /dev/null @@ -1,57 +0,0 @@ -import { Action, createReducer, on } from '@ngrx/store'; -import { EntityState, EntityAdapter, createEntityAdapter } from '@ngrx/entity'; -import { <%= classify(name) %> } from '<%= featurePath(group, flat, "models", dasherize(name)) %><%= dasherize(name) %>.model'; -import * as <%= classify(name) %>Actions from '<%= featurePath(group, flat, "actions", dasherize(name)) %><%= dasherize(name) %>.actions'; - -export const <%= pluralize(name) %>FeatureKey = '<%= pluralize(name) %>'; - -export interface State extends EntityState<<%= classify(name) %>> { - // additional entities state properties -} - -export const adapter: EntityAdapter<<%= classify(name) %>> = createEntityAdapter<<%= classify(name) %>>(); - -export const initialState: State = adapter.getInitialState({ - // additional entity state properties -}); - -export const reducer = createReducer( - initialState, - on(<%= classify(name) %>Actions.add<%= classify(name) %>, - (state, action) => adapter.addOne(action.<%= camelize(name) %>, state) - ), - on(<%= classify(name) %>Actions.upsert<%= classify(name) %>, - (state, action) => adapter.upsertOne(action.<%= camelize(name) %>, state) - ), - on(<%= classify(name) %>Actions.add<%= classify(name) %>s, - (state, action) => adapter.addMany(action.<%= camelize(name) %>s, state) - ), - on(<%= classify(name) %>Actions.upsert<%= classify(name) %>s, - (state, action) => adapter.upsertMany(action.<%= camelize(name) %>s, state) - ), - on(<%= classify(name) %>Actions.update<%= classify(name) %>, - (state, action) => adapter.updateOne(action.<%= camelize(name) %>, state) - ), - on(<%= classify(name) %>Actions.update<%= classify(name) %>s, - (state, action) => adapter.updateMany(action.<%= camelize(name) %>s, state) - ), - on(<%= classify(name) %>Actions.delete<%= classify(name) %>, - (state, action) => adapter.removeOne(action.id, state) - ), - on(<%= classify(name) %>Actions.delete<%= classify(name) %>s, - (state, action) => adapter.removeMany(action.ids, state) - ), - on(<%= classify(name) %>Actions.load<%= classify(name) %>s, - (state, action) => adapter.setAll(action.<%= camelize(name) %>s, state) - ), - on(<%= classify(name) %>Actions.clear<%= classify(name) %>s, - state => adapter.removeAll(state) - ), -); - -export const { - selectIds, - selectEntities, - selectAll, - selectTotal, -} = adapter.getSelectors(); diff --git a/modules/schematics/src/entity/files/__name@dasherize@if-flat__/__name@dasherize@group-actions__.actions.ts.template b/modules/schematics/src/entity/files/__name@dasherize@if-flat__/__name@dasherize@group-actions__.actions.ts.template index 31bec63799..9d0e837463 100644 --- a/modules/schematics/src/entity/files/__name@dasherize@if-flat__/__name@dasherize@group-actions__.actions.ts.template +++ b/modules/schematics/src/entity/files/__name@dasherize@if-flat__/__name@dasherize@group-actions__.actions.ts.template @@ -1,86 +1,53 @@ -import { Action } from '@ngrx/store'; +import { createAction, props } from '@ngrx/store'; import { Update } from '@ngrx/entity'; -import { <%= classify(name) %> } from '<%= featurePath(group, flat, "models", dasherize(name)) %><%= dasherize(name) %>.model'; - -export enum <%= classify(name) %>ActionTypes { - Load<%= classify(name) %>s = '[<%= classify(name) %>] Load <%= classify(name) %>s', - Add<%= classify(name) %> = '[<%= classify(name) %>] Add <%= classify(name) %>', - Upsert<%= classify(name) %> = '[<%= classify(name) %>] Upsert <%= classify(name) %>', - Add<%= classify(name) %>s = '[<%= classify(name) %>] Add <%= classify(name) %>s', - Upsert<%= classify(name) %>s = '[<%= classify(name) %>] Upsert <%= classify(name) %>s', - Update<%= classify(name) %> = '[<%= classify(name) %>] Update <%= classify(name) %>', - Update<%= classify(name) %>s = '[<%= classify(name) %>] Update <%= classify(name) %>s', - Delete<%= classify(name) %> = '[<%= classify(name) %>] Delete <%= classify(name) %>', - Delete<%= classify(name) %>s = '[<%= classify(name) %>] Delete <%= classify(name) %>s', - Clear<%= classify(name) %>s = '[<%= classify(name) %>] Clear <%= classify(name) %>s' -} - -export class Load<%= classify(name) %>s implements Action { - readonly type = <%= classify(name) %>ActionTypes.Load<%= classify(name) %>s; - - constructor(public payload: { <%= camelize(name) %>s: <%= classify(name) %>[] }) {} -} - -export class Add<%= classify(name) %> implements Action { - readonly type = <%= classify(name) %>ActionTypes.Add<%= classify(name) %>; - - constructor(public payload: { <%= camelize(name) %>: <%= classify(name) %> }) {} -} - -export class Upsert<%= classify(name) %> implements Action { - readonly type = <%= classify(name) %>ActionTypes.Upsert<%= classify(name) %>; - - constructor(public payload: { <%= camelize(name) %>: <%= classify(name) %> }) {} -} - -export class Add<%= classify(name) %>s implements Action { - readonly type = <%= classify(name) %>ActionTypes.Add<%= classify(name) %>s; - - constructor(public payload: { <%= camelize(name) %>s: <%= classify(name) %>[] }) {} -} - -export class Upsert<%= classify(name) %>s implements Action { - readonly type = <%= classify(name) %>ActionTypes.Upsert<%= classify(name) %>s; - constructor(public payload: { <%= camelize(name) %>s: <%= classify(name) %>[] }) {} -} - -export class Update<%= classify(name) %> implements Action { - readonly type = <%= classify(name) %>ActionTypes.Update<%= classify(name) %>; - - constructor(public payload: { <%= camelize(name) %>: Update<<%= classify(name) %>> }) {} -} - -export class Update<%= classify(name) %>s implements Action { - readonly type = <%= classify(name) %>ActionTypes.Update<%= classify(name) %>s; - - constructor(public payload: { <%= camelize(name) %>s: Update<<%= classify(name) %>>[] }) {} -} - -export class Delete<%= classify(name) %> implements Action { - readonly type = <%= classify(name) %>ActionTypes.Delete<%= classify(name) %>; - - constructor(public payload: { id: string }) {} -} - -export class Delete<%= classify(name) %>s implements Action { - readonly type = <%= classify(name) %>ActionTypes.Delete<%= classify(name) %>s; - - constructor(public payload: { ids: string[] }) {} -} - -export class Clear<%= classify(name) %>s implements Action { - readonly type = <%= classify(name) %>ActionTypes.Clear<%= classify(name) %>s; -} +import { <%= classify(name) %> } from '<%= featurePath(group, flat, "models", dasherize(name)) %><%= dasherize(name) %>.model'; -export type <%= classify(name) %>Actions = - Load<%= classify(name) %>s - | Add<%= classify(name) %> - | Upsert<%= classify(name) %> - | Add<%= classify(name) %>s - | Upsert<%= classify(name) %>s - | Update<%= classify(name) %> - | Update<%= classify(name) %>s - | Delete<%= classify(name) %> - | Delete<%= classify(name) %>s - | Clear<%= classify(name) %>s; +export const load<%= classify(name) %>s = createAction( + '[<%= classify(name) %>/API] Load <%= classify(name) %>s', + props<{ <%= camelize(name) %>s: <%= classify(name) %>[] }>() +); + +export const add<%= classify(name) %> = createAction( + '[<%= classify(name) %>/API] Add <%= classify(name) %>', + props<{ <%= camelize(name) %>: <%= classify(name) %> }>() +); + +export const upsert<%= classify(name) %> = createAction( + '[<%= classify(name) %>/API] Upsert <%= classify(name) %>', + props<{ <%= camelize(name) %>: <%= classify(name) %> }>() +); + +export const add<%= classify(name) %>s = createAction( + '[<%= classify(name) %>/API] Add <%= classify(name) %>s', + props<{ <%= camelize(name) %>s: <%= classify(name) %>[] }>() +); + +export const upsert<%= classify(name) %>s = createAction( + '[<%= classify(name) %>/API] Upsert <%= classify(name) %>s', + props<{ <%= camelize(name) %>s: <%= classify(name) %>[] }>() +); + +export const update<%= classify(name) %> = createAction( + '[<%= classify(name) %>/API] Update <%= classify(name) %>', + props<{ <%= camelize(name) %>: Update<<%= classify(name) %>> }>() +); + +export const update<%= classify(name) %>s = createAction( + '[<%= classify(name) %>/API] Update <%= classify(name) %>s', + props<{ <%= camelize(name) %>s: Update<<%= classify(name) %>>[] }>() +); + +export const delete<%= classify(name) %> = createAction( + '[<%= classify(name) %>/API] Delete <%= classify(name) %>', + props<{ id: string }>() +); + +export const delete<%= classify(name) %>s = createAction( + '[<%= classify(name) %>/API] Delete <%= classify(name) %>s', + props<{ ids: string[] }>() +); + +export const clear<%= classify(name) %>s = createAction( + '[<%= classify(name) %>/API] Clear <%= classify(name) %>s' +); diff --git a/modules/schematics/src/entity/common-files/__name@dasherize@if-flat__/__name@dasherize@group-models__.model.ts.template b/modules/schematics/src/entity/files/__name@dasherize@if-flat__/__name@dasherize@group-models__.model.ts.template similarity index 100% rename from modules/schematics/src/entity/common-files/__name@dasherize@if-flat__/__name@dasherize@group-models__.model.ts.template rename to modules/schematics/src/entity/files/__name@dasherize@if-flat__/__name@dasherize@group-models__.model.ts.template diff --git a/modules/schematics/src/entity/common-files/__name@dasherize@if-flat__/__name@dasherize@group-reducers__.reducer.spec.ts.template b/modules/schematics/src/entity/files/__name@dasherize@if-flat__/__name@dasherize@group-reducers__.reducer.spec.ts.template similarity index 100% rename from modules/schematics/src/entity/common-files/__name@dasherize@if-flat__/__name@dasherize@group-reducers__.reducer.spec.ts.template rename to modules/schematics/src/entity/files/__name@dasherize@if-flat__/__name@dasherize@group-reducers__.reducer.spec.ts.template diff --git a/modules/schematics/src/entity/files/__name@dasherize@if-flat__/__name@dasherize@group-reducers__.reducer.ts.template b/modules/schematics/src/entity/files/__name@dasherize@if-flat__/__name@dasherize@group-reducers__.reducer.ts.template index 9513693924..7439f68efd 100644 --- a/modules/schematics/src/entity/files/__name@dasherize@if-flat__/__name@dasherize@group-reducers__.reducer.ts.template +++ b/modules/schematics/src/entity/files/__name@dasherize@if-flat__/__name@dasherize@group-reducers__.reducer.ts.template @@ -1,6 +1,7 @@ +import { Action, createReducer, on } from '@ngrx/store'; import { EntityState, EntityAdapter, createEntityAdapter } from '@ngrx/entity'; import { <%= classify(name) %> } from '<%= featurePath(group, flat, "models", dasherize(name)) %><%= dasherize(name) %>.model'; -import { <%= classify(name) %>Actions, <%= classify(name) %>ActionTypes } from '<%= featurePath(group, flat, "actions", dasherize(name)) %><%= dasherize(name) %>.actions'; +import * as <%= classify(name) %>Actions from '<%= featurePath(group, flat, "actions", dasherize(name)) %><%= dasherize(name) %>.actions'; export const <%= pluralize(name) %>FeatureKey = '<%= pluralize(name) %>'; @@ -14,56 +15,39 @@ export const initialState: State = adapter.getInitialState({ // additional entity state properties }); -export function reducer( - state = initialState, - action: <%= classify(name) %>Actions -): State { - switch (action.type) { - case <%= classify(name) %>ActionTypes.Add<%= classify(name) %>: { - return adapter.addOne(action.payload.<%= camelize(name) %>, state); - } - - case <%= classify(name) %>ActionTypes.Upsert<%= classify(name) %>: { - return adapter.upsertOne(action.payload.<%= camelize(name) %>, state); - } - - case <%= classify(name) %>ActionTypes.Add<%= classify(name) %>s: { - return adapter.addMany(action.payload.<%= camelize(name) %>s, state); - } - - case <%= classify(name) %>ActionTypes.Upsert<%= classify(name) %>s: { - return adapter.upsertMany(action.payload.<%= camelize(name) %>s, state); - } - - case <%= classify(name) %>ActionTypes.Update<%= classify(name) %>: { - return adapter.updateOne(action.payload.<%= camelize(name) %>, state); - } - - case <%= classify(name) %>ActionTypes.Update<%= classify(name) %>s: { - return adapter.updateMany(action.payload.<%= camelize(name) %>s, state); - } - - case <%= classify(name) %>ActionTypes.Delete<%= classify(name) %>: { - return adapter.removeOne(action.payload.id, state); - } - - case <%= classify(name) %>ActionTypes.Delete<%= classify(name) %>s: { - return adapter.removeMany(action.payload.ids, state); - } - - case <%= classify(name) %>ActionTypes.Load<%= classify(name) %>s: { - return adapter.setAll(action.payload.<%= camelize(name) %>s, state); - } - - case <%= classify(name) %>ActionTypes.Clear<%= classify(name) %>s: { - return adapter.removeAll(state); - } - - default: { - return state; - } - } -} +export const reducer = createReducer( + initialState, + on(<%= classify(name) %>Actions.add<%= classify(name) %>, + (state, action) => adapter.addOne(action.<%= camelize(name) %>, state) + ), + on(<%= classify(name) %>Actions.upsert<%= classify(name) %>, + (state, action) => adapter.upsertOne(action.<%= camelize(name) %>, state) + ), + on(<%= classify(name) %>Actions.add<%= classify(name) %>s, + (state, action) => adapter.addMany(action.<%= camelize(name) %>s, state) + ), + on(<%= classify(name) %>Actions.upsert<%= classify(name) %>s, + (state, action) => adapter.upsertMany(action.<%= camelize(name) %>s, state) + ), + on(<%= classify(name) %>Actions.update<%= classify(name) %>, + (state, action) => adapter.updateOne(action.<%= camelize(name) %>, state) + ), + on(<%= classify(name) %>Actions.update<%= classify(name) %>s, + (state, action) => adapter.updateMany(action.<%= camelize(name) %>s, state) + ), + on(<%= classify(name) %>Actions.delete<%= classify(name) %>, + (state, action) => adapter.removeOne(action.id, state) + ), + on(<%= classify(name) %>Actions.delete<%= classify(name) %>s, + (state, action) => adapter.removeMany(action.ids, state) + ), + on(<%= classify(name) %>Actions.load<%= classify(name) %>s, + (state, action) => adapter.setAll(action.<%= camelize(name) %>s, state) + ), + on(<%= classify(name) %>Actions.clear<%= classify(name) %>s, + state => adapter.removeAll(state) + ), +); export const { selectIds, diff --git a/modules/schematics/src/entity/index.spec.ts b/modules/schematics/src/entity/index.spec.ts index 781a407ae1..ce530f7fc1 100644 --- a/modules/schematics/src/entity/index.spec.ts +++ b/modules/schematics/src/entity/index.spec.ts @@ -177,7 +177,7 @@ describe('Entity Schematic', () => { reducers: 'reducers/index.ts', }; - const reducerTree = await schematicRunner + const _reducerTree = await schematicRunner .runSchematicAsync('store', options, appTree) .toPromise(); const tree = await schematicRunner @@ -214,36 +214,32 @@ describe('Entity Schematic', () => { expect(fileContent).toMatch(/foosFeatureKey = 'foos'/); }); - describe('action creators', () => { - const creatorOptions = { ...defaultOptions, creators: true }; - - it('should create a const for the action creator', async () => { - const tree = await schematicRunner - .runSchematicAsync('entity', creatorOptions, appTree) - .toPromise(); - const fileContent = tree.readContent( - `${projectPath}/src/app/foo.actions.ts` - ); - expect(fileContent).toMatch(/export const loadFoos = createAction\(/); - expect(fileContent).toMatch(/\[Foo\/API\] Load Foos'/); - expect(fileContent).toMatch(/props<\{ foos: Foo\[\] }>\(\)/); - }); + it('should create a const for the action creator', async () => { + const tree = await schematicRunner + .runSchematicAsync('entity', defaultOptions, appTree) + .toPromise(); + const fileContent = tree.readContent( + `${projectPath}/src/app/foo.actions.ts` + ); + expect(fileContent).toMatch(/export const loadFoos = createAction\(/); + expect(fileContent).toMatch(/\[Foo\/API\] Load Foos'/); + expect(fileContent).toMatch(/props<\{ foos: Foo\[\] }>\(\)/); + }); - it('should use action creator types in the reducer', async () => { - const tree = await schematicRunner - .runSchematicAsync('entity', creatorOptions, appTree) - .toPromise(); - const fileContent = tree.readContent( - `${projectPath}/src/app/foo.reducer.ts` - ); - expect(fileContent).toMatch( - /import \* as FooActions from '\.\/foo.actions';/ - ); - expect(fileContent).toMatch(/on\(FooActions.addFoo,/); - expect(fileContent).toMatch( - /\(state, action\) => adapter\.addOne\(action.foo, state\)/ - ); - }); + it('should use action creator types in the reducer', async () => { + const tree = await schematicRunner + .runSchematicAsync('entity', defaultOptions, appTree) + .toPromise(); + const fileContent = tree.readContent( + `${projectPath}/src/app/foo.reducer.ts` + ); + expect(fileContent).toMatch( + /import \* as FooActions from '\.\/foo.actions';/ + ); + expect(fileContent).toMatch(/on\(FooActions.addFoo,/); + expect(fileContent).toMatch( + /\(state, action\) => adapter\.addOne\(action.foo, state\)/ + ); }); describe('Ivy', () => { diff --git a/modules/schematics/src/entity/index.ts b/modules/schematics/src/entity/index.ts index 2ff794b50c..790e3a4e5a 100644 --- a/modules/schematics/src/entity/index.ts +++ b/modules/schematics/src/entity/index.ts @@ -50,7 +50,7 @@ export default function (options: EntityOptions): Rule { ...(options as object), }; - const commonTemplates = apply(url('./common-files'), [ + const templateSource = apply(url('./files'), [ options.skipTests ? filter((path) => !path.endsWith('.spec.ts.template')) : noop(), @@ -58,17 +58,10 @@ export default function (options: EntityOptions): Rule { move(parsedPath.path), ]); - const templateSource = apply( - url(options.creators ? './creator-files' : './files'), - [applyTemplates(templateOptions), move(parsedPath.path)] - ); - return chain([ addReducerToState({ ...options, plural: true }), addReducerImportToNgModule({ ...options, plural: true }), - branchAndMerge( - chain([mergeWith(commonTemplates), mergeWith(templateSource)]) - ), + branchAndMerge(mergeWith(templateSource)), ])(host, context); }; } diff --git a/modules/schematics/src/entity/schema.json b/modules/schematics/src/entity/schema.json index 1b70779805..4c143b8f45 100644 --- a/modules/schematics/src/entity/schema.json +++ b/modules/schematics/src/entity/schema.json @@ -49,13 +49,6 @@ "default": false, "description": "Group actions, reducers and effects within relative subfolders", "aliases": ["g"] - }, - "creators": { - "type": "boolean", - "default": true, - "description": "Specifies whether to use creator functions for handling actions and reducers.", - "aliases": ["c"], - "x-prompt": "Do you want to use the create function?" } }, "required": [] diff --git a/modules/schematics/src/entity/schema.ts b/modules/schematics/src/entity/schema.ts index ff6e7ab78f..1d5db1236f 100644 --- a/modules/schematics/src/entity/schema.ts +++ b/modules/schematics/src/entity/schema.ts @@ -36,10 +36,4 @@ export interface Schema { */ group?: boolean; - - /** - * Specifies whether to use creator functions for - * handling actions and reducers. - */ - creators?: boolean; } diff --git a/modules/schematics/src/feature/index.spec.ts b/modules/schematics/src/feature/index.spec.ts index 92b702af08..00ecbd3d2e 100644 --- a/modules/schematics/src/feature/index.spec.ts +++ b/modules/schematics/src/feature/index.spec.ts @@ -39,29 +39,29 @@ describe('Feature Schematic', () => { .toPromise(); const files = tree.files; expect( - files.indexOf(`${projectPath}/src/app/foo.actions.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${projectPath}/src/app/foo.actions.ts`) + ).toBeTruthy(); expect( - files.indexOf(`${projectPath}/src/app/foo.actions.spec.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${projectPath}/src/app/foo.actions.spec.ts`) + ).toBeFalsy(); expect( - files.indexOf(`${projectPath}/src/app/foo.reducer.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${projectPath}/src/app/foo.reducer.ts`) + ).toBeTruthy(); expect( - files.indexOf(`${projectPath}/src/app/foo.reducer.spec.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${projectPath}/src/app/foo.reducer.spec.ts`) + ).toBeTruthy(); expect( - files.indexOf(`${projectPath}/src/app/foo.effects.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${projectPath}/src/app/foo.effects.ts`) + ).toBeTruthy(); expect( - files.indexOf(`${projectPath}/src/app/foo.effects.spec.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${projectPath}/src/app/foo.effects.spec.ts`) + ).toBeTruthy(); expect( - files.indexOf(`${projectPath}/src/app/foo.selectors.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${projectPath}/src/app/foo.selectors.ts`) + ).toBeTruthy(); expect( - files.indexOf(`${projectPath}/src/app/foo.selectors.spec.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${projectPath}/src/app/foo.selectors.spec.ts`) + ).toBeTruthy(); }); it('should not create test files', async () => { @@ -72,29 +72,29 @@ describe('Feature Schematic', () => { .toPromise(); const files = tree.files; expect( - files.indexOf(`${projectPath}/src/app/foo.actions.ts`) - ).toBeGreaterThanOrEqual(0); - expect(files.indexOf(`${projectPath}/src/app/foo.actions.spec.ts`)).toEqual( - -1 - ); + files.includes(`${projectPath}/src/app/foo.actions.ts`) + ).toBeTruthy(); expect( - files.indexOf(`${projectPath}/src/app/foo.reducer.ts`) - ).toBeGreaterThanOrEqual(0); - expect(files.indexOf(`${projectPath}/src/app/foo.reducer.spec.ts`)).toEqual( - -1 - ); + files.includes(`${projectPath}/src/app/foo.actions.spec.ts`) + ).toBeFalsy(); expect( - files.indexOf(`${projectPath}/src/app/foo.effects.ts`) - ).toBeGreaterThanOrEqual(0); - expect(files.indexOf(`${projectPath}/src/app/foo.effects.spec.ts`)).toEqual( - -1 - ); + files.includes(`${projectPath}/src/app/foo.reducer.ts`) + ).toBeTruthy(); + expect( + files.includes(`${projectPath}/src/app/foo.reducer.spec.ts`) + ).toBeFalsy(); + expect( + files.includes(`${projectPath}/src/app/foo.effects.ts`) + ).toBeTruthy(); + expect( + files.includes(`${projectPath}/src/app/foo.effects.spec.ts`) + ).toBeFalsy(); expect( - files.indexOf(`${projectPath}/src/app/foo.selectors.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${projectPath}/src/app/foo.selectors.ts`) + ).toBeTruthy(); expect( - files.indexOf(`${projectPath}/src/app/foo.selectors.spec.ts`) - ).toEqual(-1); + files.includes(`${projectPath}/src/app/foo.selectors.spec.ts`) + ).toBeFalsy(); }); it('should create all files of a feature to specified project if provided', async () => { @@ -113,29 +113,29 @@ describe('Feature Schematic', () => { .toPromise(); const files = tree.files; expect( - files.indexOf(`${specifiedProjectPath}/src/lib/foo.actions.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${specifiedProjectPath}/src/lib/foo.actions.ts`) + ).toBeTruthy(); expect( - files.indexOf(`${specifiedProjectPath}/src/lib/foo.actions.spec.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${specifiedProjectPath}/src/lib/foo.actions.spec.ts`) + ).toBeFalsy(); expect( - files.indexOf(`${specifiedProjectPath}/src/lib/foo.reducer.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${specifiedProjectPath}/src/lib/foo.reducer.ts`) + ).toBeTruthy(); expect( - files.indexOf(`${specifiedProjectPath}/src/lib/foo.reducer.spec.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${specifiedProjectPath}/src/lib/foo.reducer.spec.ts`) + ).toBeTruthy(); expect( - files.indexOf(`${specifiedProjectPath}/src/lib/foo.effects.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${specifiedProjectPath}/src/lib/foo.effects.ts`) + ).toBeTruthy(); expect( - files.indexOf(`${specifiedProjectPath}/src/lib/foo.effects.spec.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${specifiedProjectPath}/src/lib/foo.effects.spec.ts`) + ).toBeTruthy(); expect( - files.indexOf(`${specifiedProjectPath}/src/lib/foo.selectors.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${specifiedProjectPath}/src/lib/foo.selectors.ts`) + ).toBeTruthy(); expect( - files.indexOf(`${specifiedProjectPath}/src/lib/foo.selectors.spec.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${specifiedProjectPath}/src/lib/foo.selectors.spec.ts`) + ).toBeTruthy(); }); it('should create all files of a feature within grouped folders if group is set', async () => { @@ -146,26 +146,26 @@ describe('Feature Schematic', () => { .toPromise(); const files = tree.files; expect( - files.indexOf(`${projectPath}/src/app/actions/foo.actions.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${projectPath}/src/app/actions/foo.actions.ts`) + ).toBeTruthy(); expect( - files.indexOf(`${projectPath}/src/app/reducers/foo.reducer.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${projectPath}/src/app/reducers/foo.reducer.ts`) + ).toBeTruthy(); expect( - files.indexOf(`${projectPath}/src/app/reducers/foo.reducer.spec.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${projectPath}/src/app/reducers/foo.reducer.spec.ts`) + ).toBeTruthy(); expect( - files.indexOf(`${projectPath}/src/app/effects/foo.effects.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${projectPath}/src/app/effects/foo.effects.ts`) + ).toBeTruthy(); expect( - files.indexOf(`${projectPath}/src/app/effects/foo.effects.spec.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${projectPath}/src/app/effects/foo.effects.spec.ts`) + ).toBeTruthy(); expect( - files.indexOf(`${projectPath}/src/app/selectors/foo.selectors.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${projectPath}/src/app/selectors/foo.selectors.ts`) + ).toBeTruthy(); expect( - files.indexOf(`${projectPath}/src/app/selectors/foo.selectors.spec.ts`) - ).toBeGreaterThanOrEqual(0); + files.includes(`${projectPath}/src/app/selectors/foo.selectors.spec.ts`) + ).toBeTruthy(); }); it('should respect the path provided for the feature name', async () => { @@ -191,25 +191,6 @@ describe('Feature Schematic', () => { ); }); - it('should have all three api actions in actions type union if api flag enabled and creators=false', async () => { - const options = { - ...defaultOptions, - api: true, - creators: false, - }; - - const tree = await schematicRunner - .runSchematicAsync('feature', options, appTree) - .toPromise(); - const fileContent = tree.readContent( - `${projectPath}/src/app/foo.actions.ts` - ); - - expect(fileContent).toMatch( - /export type FooActions = LoadFoos \| LoadFoosSuccess \| LoadFoosFailure/ - ); - }); - it('should have all api effect if api flag enabled', async () => { const options = { ...defaultOptions, diff --git a/modules/schematics/src/feature/index.ts b/modules/schematics/src/feature/index.ts index f2ef904ff9..71b3e6416a 100644 --- a/modules/schematics/src/feature/index.ts +++ b/modules/schematics/src/feature/index.ts @@ -18,7 +18,6 @@ export default function (options: FeatureOptions): Rule { project: options.project, skipTests: options.skipTests, api: options.api, - creators: options.creators, prefix: options.prefix, }), schematic('reducer', { @@ -32,7 +31,6 @@ export default function (options: FeatureOptions): Rule { reducers: options.reducers, feature: true, api: options.api, - creators: options.creators, prefix: options.prefix, }), schematic('effect', { @@ -45,7 +43,6 @@ export default function (options: FeatureOptions): Rule { skipTests: options.skipTests, feature: true, api: options.api, - creators: options.creators, prefix: options.prefix, }), schematic('selector', { diff --git a/modules/schematics/src/feature/schema.json b/modules/schematics/src/feature/schema.json index b0270311d1..ba11215ff6 100644 --- a/modules/schematics/src/feature/schema.json +++ b/modules/schematics/src/feature/schema.json @@ -57,13 +57,6 @@ "aliases": ["a"], "x-prompt": "Should we generate and wire success and failure actions?" }, - "creators": { - "type": "boolean", - "default": true, - "description": "Specifies if the actions, reducers, and effects should be created using creator functions", - "aliases": ["c"], - "x-prompt": "Do you want to use the create functions?" - }, "prefix": { "description": "The prefix of the action, effect and reducer.", "type": "string", diff --git a/modules/schematics/src/feature/schema.ts b/modules/schematics/src/feature/schema.ts index 1c0491a7b0..a5413b7555 100644 --- a/modules/schematics/src/feature/schema.ts +++ b/modules/schematics/src/feature/schema.ts @@ -45,10 +45,5 @@ export interface Schema { */ api?: boolean; - /** - * Specifies whether to use creator functions for actions, reducers, and effects. - */ - creators?: boolean; - prefix?: string; } diff --git a/modules/schematics/src/reducer/creator-files/__name@dasherize@if-flat__/__name@dasherize__.reducer.ts.template b/modules/schematics/src/reducer/creator-files/__name@dasherize@if-flat__/__name@dasherize__.reducer.ts.template deleted file mode 100644 index f9055a82d8..0000000000 --- a/modules/schematics/src/reducer/creator-files/__name@dasherize@if-flat__/__name@dasherize__.reducer.ts.template +++ /dev/null @@ -1,21 +0,0 @@ -import { Action, createReducer, on } from '@ngrx/store'; -<% if(feature) { %>import * as <%= classify(name) %>Actions from '<%= featurePath(group, flat, "actions", dasherize(name)) %><%= dasherize(name) %>.actions';<% } %> - -export const <%= camelize(name) %>FeatureKey = '<%= camelize(name) %>'; - -export interface State { - -} - -export const initialState: State = { - -}; - -export const reducer = createReducer( - initialState, -<% if(feature) { %> - on(<%= classify(name) %>Actions.<%= prefix %><%= classify(name) %>s, state => state), -<% if(api) { %> on(<%= classify(name) %>Actions.<%= prefix %><%= classify(name) %>sSuccess, (state, action) => state), - on(<%= classify(name) %>Actions.<%= prefix %><%= classify(name) %>sFailure, (state, action) => state), -<% } %><% } %> -); diff --git a/modules/schematics/src/reducer/common-files/__name@dasherize@if-flat__/__name@dasherize__.reducer.spec.ts.template b/modules/schematics/src/reducer/files/__name@dasherize@if-flat__/__name@dasherize__.reducer.spec.ts.template similarity index 100% rename from modules/schematics/src/reducer/common-files/__name@dasherize@if-flat__/__name@dasherize__.reducer.spec.ts.template rename to modules/schematics/src/reducer/files/__name@dasherize@if-flat__/__name@dasherize__.reducer.spec.ts.template diff --git a/modules/schematics/src/reducer/files/__name@dasherize@if-flat__/__name@dasherize__.reducer.ts.template b/modules/schematics/src/reducer/files/__name@dasherize@if-flat__/__name@dasherize__.reducer.ts.template index 0fcbc4633d..f9055a82d8 100644 --- a/modules/schematics/src/reducer/files/__name@dasherize@if-flat__/__name@dasherize__.reducer.ts.template +++ b/modules/schematics/src/reducer/files/__name@dasherize@if-flat__/__name@dasherize__.reducer.ts.template @@ -1,5 +1,5 @@ -<% if(!feature) { %>import { Action } from '@ngrx/store';<% } %> -<% if(feature) { %>import { <%= classify(name) %>Actions, <%= classify(name) %>ActionTypes } from '<%= featurePath(group, flat, "actions", dasherize(name)) %><%= dasherize(name) %>.actions';<% } %> +import { Action, createReducer, on } from '@ngrx/store'; +<% if(feature) { %>import * as <%= classify(name) %>Actions from '<%= featurePath(group, flat, "actions", dasherize(name)) %><%= dasherize(name) %>.actions';<% } %> export const <%= camelize(name) %>FeatureKey = '<%= camelize(name) %>'; @@ -11,19 +11,11 @@ export const initialState: State = { }; -export function reducer(state = initialState, action: <% if(feature) { %><%= classify(name) %>Actions<% } else { %>Action<% } %>): State { - switch (action.type) { +export const reducer = createReducer( + initialState, <% if(feature) { %> - case <%= classify(name) %>ActionTypes.<%= prefix %><%= classify(name) %>s: - return state; -<% if(api) { %> - case <%= classify(name) %>ActionTypes.<%= prefix %><%= classify(name) %>sSuccess: - return state; - - case <%= classify(name) %>ActionTypes.<%= prefix %><%= classify(name) %>sFailure: - return state; + on(<%= classify(name) %>Actions.<%= prefix %><%= classify(name) %>s, state => state), +<% if(api) { %> on(<%= classify(name) %>Actions.<%= prefix %><%= classify(name) %>sSuccess, (state, action) => state), + on(<%= classify(name) %>Actions.<%= prefix %><%= classify(name) %>sFailure, (state, action) => state), <% } %><% } %> - default: - return state; - } -} +); diff --git a/modules/schematics/src/reducer/index.spec.ts b/modules/schematics/src/reducer/index.spec.ts index 8c55071c6b..edfdc13dba 100644 --- a/modules/schematics/src/reducer/index.spec.ts +++ b/modules/schematics/src/reducer/index.spec.ts @@ -231,28 +231,6 @@ describe('Reducer Schematic', () => { ); }); - it('should create an reducer function with api success and failure, given creators=false, feature and api', async () => { - const tree = await schematicRunner - .runSchematicAsync( - 'reducer', - { - ...defaultOptions, - feature: true, - api: true, - creators: false, - }, - appTree - ) - .toPromise(); - const fileContent = tree.readContent( - `${projectPath}/src/app/foo.reducer.ts` - ); - - expect(fileContent).toMatch(/case FooActionTypes\.LoadFoosSuccess/); - expect(fileContent).toMatch(/case FooActionTypes\.LoadFoosFailure/); - expect(fileContent).not.toMatch(/import { Action } from '@ngrx\/store'/); - }); - it('should create a reducer with prefix in an api feature', async () => { const tree = await schematicRunner .runSchematicAsync( diff --git a/modules/schematics/src/reducer/index.ts b/modules/schematics/src/reducer/index.ts index 94ee145c9e..7eb0564a8b 100644 --- a/modules/schematics/src/reducer/index.ts +++ b/modules/schematics/src/reducer/index.ts @@ -51,7 +51,7 @@ export default function (options: ReducerOptions): Rule { ...(options as object), }; - const commonTemplate = apply(url('./common-files'), [ + const templateSource = apply(url('./files'), [ options.skipTests ? filter((path) => !path.endsWith('.spec.ts.template')) : noop(), @@ -59,19 +59,10 @@ export default function (options: ReducerOptions): Rule { move(parsedPath.path), ]); - const templateSource = apply( - url(options.creators ? './creator-files' : './files'), - [applyTemplates(templateOptions), move(parsedPath.path)] - ); - return chain([ branchAndMerge(chain([addReducerToState(options)])), branchAndMerge( - chain([ - addReducerImportToNgModule(options), - mergeWith(commonTemplate), - mergeWith(templateSource), - ]) + chain([addReducerImportToNgModule(options), mergeWith(templateSource)]) ), ])(host, context); }; diff --git a/modules/schematics/src/reducer/schema.json b/modules/schematics/src/reducer/schema.json index 1b6ca93c75..e9a23997d3 100644 --- a/modules/schematics/src/reducer/schema.json +++ b/modules/schematics/src/reducer/schema.json @@ -61,13 +61,6 @@ "description": "Specifies if api success and failure actions should be added to the reducer", "aliases": ["a"], "x-prompt": "Should we add success and failure actions to the reducer?" - }, - "creators": { - "type": "boolean", - "default": true, - "description": "Specifies whether to use creator functions for handling actions and reducers.", - "aliases": ["c"], - "x-prompt": "Do you want to use the create function?" } }, "prefix": { diff --git a/modules/schematics/src/reducer/schema.ts b/modules/schematics/src/reducer/schema.ts index 4d1be8679e..7739db7da0 100644 --- a/modules/schematics/src/reducer/schema.ts +++ b/modules/schematics/src/reducer/schema.ts @@ -50,12 +50,6 @@ export interface Schema { */ api?: boolean; - /** - * Specifies whether to use creator functions for - * handling actions and reducers. - */ - creators?: boolean; - /** * The prefix for the reducers. */ diff --git a/modules/store-devtools/schematics-core/utility/ngrx-utils.ts b/modules/store-devtools/schematics-core/utility/ngrx-utils.ts index 4e8c8d8f6e..cf58124fce 100644 --- a/modules/store-devtools/schematics-core/utility/ngrx-utils.ts +++ b/modules/store-devtools/schematics-core/utility/ngrx-utils.ts @@ -269,8 +269,6 @@ export function omit( .reduce((result, key) => Object.assign(result, { [key]: object[key] }), {}); } -export function getPrefix(options: { prefix?: string; creators?: boolean }) { - return options.creators - ? stringUtils.camelize(options.prefix || 'load') - : stringUtils.capitalize(options.prefix || 'load'); +export function getPrefix(options: { prefix?: string }) { + return stringUtils.camelize(options.prefix || 'load'); } diff --git a/modules/store/schematics-core/utility/ngrx-utils.ts b/modules/store/schematics-core/utility/ngrx-utils.ts index 4e8c8d8f6e..cf58124fce 100644 --- a/modules/store/schematics-core/utility/ngrx-utils.ts +++ b/modules/store/schematics-core/utility/ngrx-utils.ts @@ -269,8 +269,6 @@ export function omit( .reduce((result, key) => Object.assign(result, { [key]: object[key] }), {}); } -export function getPrefix(options: { prefix?: string; creators?: boolean }) { - return options.creators - ? stringUtils.camelize(options.prefix || 'load') - : stringUtils.capitalize(options.prefix || 'load'); +export function getPrefix(options: { prefix?: string }) { + return stringUtils.camelize(options.prefix || 'load'); } diff --git a/projects/ngrx.io/content/guide/schematics/action.md b/projects/ngrx.io/content/guide/schematics/action.md index 446a34d3fe..319a9562fd 100644 --- a/projects/ngrx.io/content/guide/schematics/action.md +++ b/projects/ngrx.io/content/guide/schematics/action.md @@ -27,13 +27,6 @@ Provide the project name where the action files will be created. - Alias: `-p` - Type: `string` -Use creator functions for actions - -- `--creators` - - Alias: `-c` - - Type: `boolean` - - Default: `true` - Nest the actions file within a folder based on the action `name`. - `--flat` diff --git a/projects/ngrx.io/content/guide/schematics/effect.md b/projects/ngrx.io/content/guide/schematics/effect.md index b147bcf08f..2423467e45 100644 --- a/projects/ngrx.io/content/guide/schematics/effect.md +++ b/projects/ngrx.io/content/guide/schematics/effect.md @@ -26,13 +26,6 @@ Provide the project name where the effect files will be created. - Alias: `-p` - Type: `string` -Use creator functions for actions and effects. - -- `--creators` - - Alias: `-c` - - Type: `boolean` - - Default: `true` - Nest the effects file within a folder based by the effect `name`. - `--flat` diff --git a/projects/ngrx.io/content/guide/schematics/entity.md b/projects/ngrx.io/content/guide/schematics/entity.md index 34289be303..133ee38df8 100644 --- a/projects/ngrx.io/content/guide/schematics/entity.md +++ b/projects/ngrx.io/content/guide/schematics/entity.md @@ -26,13 +26,6 @@ Provide the project name where the entity files will be created. - Alias: `-p` - Type: `string` -Use creator functions for actions, reducers, and effects. - -- `--creators` - - Alias: `-c` - - Type: `boolean` - - Default: `true` - Nest the effects file within a folder based on the entity `name`. - `--flat` diff --git a/projects/ngrx.io/content/guide/schematics/feature.md b/projects/ngrx.io/content/guide/schematics/feature.md index 51fe981305..ecc9ad1678 100644 --- a/projects/ngrx.io/content/guide/schematics/feature.md +++ b/projects/ngrx.io/content/guide/schematics/feature.md @@ -26,13 +26,6 @@ Provide the project name where the feature files will be created. - Alias: `-p` - Type: `string` -Use creator functions for actions, reducers, and effects. - -- `--creators` - - Alias: `-c` - - Type: `boolean` - - Default: `true` - Nest the feature files within a folder based on the feature `name`. - `--flat` diff --git a/projects/ngrx.io/content/guide/schematics/reducer.md b/projects/ngrx.io/content/guide/schematics/reducer.md index 11cb760290..0f3c4f18ae 100644 --- a/projects/ngrx.io/content/guide/schematics/reducer.md +++ b/projects/ngrx.io/content/guide/schematics/reducer.md @@ -27,13 +27,6 @@ Provide the project name where the reducer files will be created. - Alias: `-p` - Type: `string` -Use creator functions to generate the actions and reducer. - -- `--creators` - - Alias: `-c` - - Type: `boolean` - - Default: `true` - Nest the reducer file within a folder based on the reducer `name`. - `--flat`