cleanup(angular): remove deprecated DataPersistence service and generator option to use it (#12236)

This commit is contained in:
Leosvel Pérez Espinosa 2022-09-28 16:13:43 +01:00 committed by GitHub
parent 09c6ccb266
commit b3676e8019
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 22 additions and 266 deletions

View File

@ -1569,12 +1569,6 @@
"default": false,
"description": "Do not update the `package.json` with NgRx dependencies."
},
"useDataPersistence": {
"type": "boolean",
"default": false,
"description": "Generate NgRx Effects with the `DataPersistence` helper service. Set to false to use plain effects data persistence operators.",
"x-deprecated": "This option is deprecated and will be removed in v15. Using the individual operators is recommended."
},
"barrels": {
"type": "boolean",
"default": false,

View File

@ -27,7 +27,7 @@ describe('Angular Package', () => {
// Generate root ngrx state management
runCLI(
`generate @nrwl/angular:ngrx users --module=apps/${myapp}/src/app/app.module.ts --root --minimal=false --useDataPersistence=true`
`generate @nrwl/angular:ngrx users --module=apps/${myapp}/src/app/app.module.ts --root --minimal=false`
);
const packageJson = readJson('package.json');
expect(packageJson.dependencies['@ngrx/store']).toBeDefined();

View File

@ -1,8 +1,6 @@
export {
DataPersistence,
fetch,
navigation,
optimisticUpdate,
pessimisticUpdate,
} from './src/runtime/nx/data-persistence';
export { NxModule } from './src/runtime/nx/nx.module';

View File

@ -5,7 +5,6 @@ exports[`ngrx generated unit tests should generate specs for the ngrx effects 1`
import { provideMockActions } from '@ngrx/effects/testing';
import { Action } from '@ngrx/store';
import { provideMockStore } from '@ngrx/store/testing';
import { NxModule } from '@nrwl/angular';
import { hot } from 'jasmine-marbles';
import { Observable } from 'rxjs';
@ -18,9 +17,7 @@ describe('SuperUsersEffects', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
NxModule.forRoot(),
],
imports: [],
providers: [
SuperUsersEffects,
provideMockActions(() => actions),
@ -44,57 +41,11 @@ describe('SuperUsersEffects', () => {
"
`;
exports[`ngrx generated unit tests should generate specs for the ngrx effects correctly when useDataPersistence is true 1`] = `
"import { TestBed } from '@angular/core/testing';
import { provideMockActions } from '@ngrx/effects/testing';
import { Action } from '@ngrx/store';
import { provideMockStore } from '@ngrx/store/testing';
import { NxModule, DataPersistence } from '@nrwl/angular';
import { hot } from 'jasmine-marbles';
import { Observable } from 'rxjs';
import * as SuperUsersActions from './super-users.actions';
import { SuperUsersEffects } from './super-users.effects';
describe('SuperUsersEffects', () => {
let actions: Observable<Action>;
let effects: SuperUsersEffects;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
NxModule.forRoot(),
],
providers: [
SuperUsersEffects,
DataPersistence,
provideMockActions(() => actions),
provideMockStore()
],
});
effects = TestBed.inject(SuperUsersEffects);
});
describe('init$', () => {
it('should work', () => {
actions = hot('-a-|', { a: SuperUsersActions.initSuperUsers() });
const expected = hot('-a-|', { a: SuperUsersActions.loadSuperUsersSuccess({ superUsers: [] }) });
expect(effects.init$).toBeObservable(expected);
});
});
});
"
`;
exports[`ngrx generated unit tests should generate specs for the ngrx facade 1`] = `
"import { NgModule } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { EffectsModule } from '@ngrx/effects';
import { StoreModule, Store } from '@ngrx/store';
import { NxModule } from '@nrwl/angular';
import { readFirst } from '@nrwl/angular/testing';
import * as SuperUsersActions from './super-users.actions';
@ -134,7 +85,6 @@ describe('SuperUsersFacade', () => {
@NgModule({
imports: [
NxModule.forRoot(),
StoreModule.forRoot({}),
EffectsModule.forRoot([]),
CustomFeatureModule,
@ -307,12 +257,11 @@ import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
import * as fromUsers from './+state/users.reducer';
import { UsersEffects } from './+state/users.effects';
import { NxModule } from '@nrwl/angular';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { environment } from '../environments/environment';
import { StoreRouterConnectingModule } from '@ngrx/router-store';
@NgModule({
imports: [BrowserModule, RouterModule.forRoot([]), NxModule.forRoot(), StoreModule.forRoot({}, {
imports: [BrowserModule, RouterModule.forRoot([]), StoreModule.forRoot({}, {
metaReducers: !environment.production ? [] : [],
runtimeChecks: {
strictActionImmutability: true,
@ -395,7 +344,7 @@ export class UsersEffects {
init$ = createEffect(() => this.actions$.pipe(
ofType(UsersActions.initUsers),
fetch({
run: action => {
run: (action) => {
// Your custom service 'load' logic goes here. For now just return a success action...
return UsersActions.loadUsersSuccess({ users: [] });
},
@ -406,9 +355,7 @@ export class UsersEffects {
})
));
constructor(
private readonly actions$: Actions
) {}
constructor(private readonly actions$: Actions) {}
}
"
`;
@ -583,32 +530,3 @@ export * from './lib/+state/super-users.actions';
export * from './lib/flights.module';
"
`;
exports[`ngrx should use DataPersistence when useDataPersistence is true 1`] = `
"import { Injectable } from '@angular/core';
import { createEffect, Actions, ofType } from '@ngrx/effects';
import { DataPersistence } from '@nrwl/angular';
import * as UsersActions from './users.actions';
import * as UsersFeature from './users.reducer';
@Injectable()
export class UsersEffects {
init$ = createEffect(() => this.dataPersistence.fetch(UsersActions.initUsers, {
run: (action: ReturnType<typeof UsersActions.initUsers>, state: UsersFeature.UsersPartialState) => {
// Your custom service 'load' logic goes here. For now just return a success action...
return UsersActions.loadUsersSuccess({ users: [] });
},
onError: (action: ReturnType<typeof UsersActions.initUsers>, error) => {
console.error('Error', error);
return UsersActions.loadUsersFailure({ error });
}
}));
constructor(
private readonly actions$: Actions,
private readonly dataPersistence: DataPersistence<UsersFeature.UsersPartialState>
) {}
}
"
`;

View File

@ -2,7 +2,6 @@ import { TestBed } from '@angular/core/testing';
import { provideMockActions } from '@ngrx/effects/testing';
import { Action } from '@ngrx/store';
import { provideMockStore } from '@ngrx/store/testing';
import { NxModule<% if (useDataPersistence) { %>, DataPersistence<% } %> } from '@nrwl/angular';
import { hot } from 'jasmine-marbles';
import { Observable } from 'rxjs';
@ -15,12 +14,9 @@ describe('<%= className %>Effects', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
NxModule.forRoot(),
],
imports: [],
providers: [
<%= className %>Effects,<% if (useDataPersistence) { %>
DataPersistence,<% } %>
<%= className %>Effects,
provideMockActions(() => actions),
provideMockStore()
],

View File

@ -1,25 +1,16 @@
import { Injectable } from '@angular/core';
import { createEffect, Actions, ofType } from '@ngrx/effects';
import { <% if (useDataPersistence) { %>DataPersistence<% } %><% if (!useDataPersistence) { %>fetch<% } %> } from '@nrwl/angular';
import { fetch } from '@nrwl/angular';
import * as <%= className %>Actions from './<%= fileName %>.actions';
import * as <%= className %>Feature from './<%= fileName %>.reducer';
@Injectable()
export class <%= className %>Effects {
<% if (useDataPersistence) { %>init$ = createEffect(() => this.dataPersistence.fetch(<%= className %>Actions.init<%= className %>, {
run: (action: ReturnType<typeof <%= className %>Actions.init<%= className %>>, state: <%= className %>Feature.<%= className %>PartialState) => {
// Your custom service 'load' logic goes here. For now just return a success action...
return <%= className %>Actions.load<%= className %>Success({ <%= propertyName %>: [] });
},
onError: (action: ReturnType<typeof <%= className %>Actions.init<%= className %>>, error) => {
console.error('Error', error);
return <%= className %>Actions.load<%= className %>Failure({ error });
}
}));<% } else { %>init$ = createEffect(() => this.actions$.pipe(
init$ = createEffect(() => this.actions$.pipe(
ofType(<%= className %>Actions.init<%= className %>),
fetch({
run: action => {
run: (action) => {
// Your custom service 'load' logic goes here. For now just return a success action...
return <%= className %>Actions.load<%= className %>Success({ <%= propertyName %>: [] });
},
@ -28,10 +19,7 @@ export class <%= className %>Effects {
return <%= className %>Actions.load<%= className %>Failure({ error });
}
})
));<% } %>
));
constructor(
private readonly actions$: Actions<% if (useDataPersistence) { %>,
private readonly dataPersistence: DataPersistence<<%= className %>Feature.<%= className %>PartialState><% } %>
) {}
constructor(private readonly actions$: Actions) {}
}

View File

@ -2,7 +2,6 @@ import { NgModule } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { EffectsModule } from '@ngrx/effects';
import { StoreModule, Store } from '@ngrx/store';
import { NxModule } from '@nrwl/angular';
import { readFirst } from '@nrwl/angular/testing';
import * as <%= className %>Actions from './<%= fileName %>.actions';
@ -42,7 +41,6 @@ describe('<%= className %>Facade', () => {
@NgModule({
imports: [
NxModule.forRoot(),
StoreModule.forRoot({}),
EffectsModule.forRoot([]),
CustomFeatureModule,

View File

@ -59,7 +59,6 @@ export function addImportsToModule(
strictStateImmutability: true
}
})`;
const nxModule = 'NxModule.forRoot()';
const effectsForRoot = `EffectsModule.forRoot([${effectsName}])`;
const effectsForEmptyRoot = `EffectsModule.forRoot([])`;
const storeForFeature = `StoreModule.forFeature(from${className}.${constantName}_FEATURE_KEY, from${className}.${propertyName}Reducer)`;
@ -69,7 +68,6 @@ export function addImportsToModule(
// this is just a heuristic
const hasRouter = sourceText.indexOf('RouterModule') > -1;
const hasNxModule = sourceText.includes(nxModule);
sourceFile = addImport(sourceFile, 'StoreModule', '@ngrx/store');
sourceFile = addImport(sourceFile, 'EffectsModule', '@ngrx/effects');
@ -129,11 +127,6 @@ export function addImportsToModule(
if (options.root) {
sourceFile = addCommonImports();
if (!hasNxModule) {
sourceFile = addImport(sourceFile, 'NxModule', '@nrwl/angular');
sourceFile = addImportToModule(tree, sourceFile, modulePath, nxModule);
}
sourceFile = addImport(
sourceFile,
'StoreDevtoolsModule',

View File

@ -23,7 +23,6 @@ describe('ngrx', () => {
minimal: true,
module: 'apps/myapp/src/app/app.module.ts',
name: 'users',
useDataPersistence: false,
};
const expectFileToExist = (file: string) =>
@ -312,19 +311,6 @@ describe('ngrx', () => {
).toMatchSnapshot();
});
it('should use DataPersistence when useDataPersistence is true', async () => {
await ngrxGenerator(tree, {
...defaultOptions,
module: appConfig.appModule,
minimal: false,
useDataPersistence: true,
});
expect(
tree.read(`${statePath}/users.effects.ts`, 'utf-8')
).toMatchSnapshot();
});
it('should generate with custom directory', async () => {
statePath = '/apps/myapp/src/app/my-custom-directory';
@ -420,20 +406,6 @@ describe('ngrx', () => {
).toMatchSnapshot();
});
it('should generate specs for the ngrx effects correctly when useDataPersistence is true', async () => {
await ngrxGenerator(tree, {
...defaultOptions,
name: 'super-users',
module: appConfig.appModule,
minimal: false,
useDataPersistence: true,
});
expect(
tree.read(`${statePath}/super-users.effects.spec.ts`, 'utf-8')
).toMatchSnapshot();
});
it('should generate specs for the ngrx facade', async () => {
await ngrxGenerator(tree, {
...defaultOptions,

View File

@ -9,9 +9,4 @@ export interface NgRxGeneratorOptions {
skipFormat?: boolean;
skipImport?: boolean;
skipPackageJson?: boolean;
/**
* @deprecated This option is deprecated and will be removed in v15.
* Using the individual operators is recommended.
*/
useDataPersistence?: boolean;
}

View File

@ -57,12 +57,6 @@
"default": false,
"description": "Do not update the `package.json` with NgRx dependencies."
},
"useDataPersistence": {
"type": "boolean",
"default": false,
"description": "Generate NgRx Effects with the `DataPersistence` helper service. Set to false to use plain effects data persistence operators.",
"x-deprecated": "This option is deprecated and will be removed in v15. Using the individual operators is recommended."
},
"barrels": {
"type": "boolean",
"default": false,

View File

@ -1,9 +1,13 @@
import { Injectable, Type } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Actions, ofType } from '@ngrx/effects';
import { ROUTER_NAVIGATION, RouterNavigationAction } from '@ngrx/router-store';
import { Action, Store, ActionCreator } from '@ngrx/store';
import { isObservable, Observable, of } from 'rxjs';
import type { Type } from '@angular/core';
import type {
ActivatedRouteSnapshot,
RouterStateSnapshot,
} from '@angular/router';
import type { RouterNavigationAction } from '@ngrx/router-store';
import { ROUTER_NAVIGATION } from '@ngrx/router-store';
import type { Action } from '@ngrx/store';
import type { Observable } from 'rxjs';
import { isObservable, of } from 'rxjs';
import {
catchError,
concatMap,
@ -12,7 +16,6 @@ import {
map,
mergeMap,
switchMap,
withLatestFrom,
} from 'rxjs/operators';
export interface PessimisticUpdateOpts<T extends Array<unknown>, A> {
@ -418,83 +421,6 @@ function normalizeActionAndState<T extends Array<unknown>, A>(
return [action, ...slices];
}
/**
* @whatItDoes Provides convenience methods for implementing common operations of persisting data.
*
* @deprecated Use the individual operators instead. Will be removed in v15.
*/
@Injectable()
export class DataPersistence<T> {
constructor(public store: Store<T>, public actions: Actions) {}
/**
* See {@link pessimisticUpdate} operator for more information.
*
* @deprecated Use the {@link pessimisticUpdate} operator instead.
* The {@link DataPersistence} class will be removed in v15.
*/
pessimisticUpdate<A extends Action = Action>(
actionType: string | ActionCreator,
opts: PessimisticUpdateOpts<[T], A>
): Observable<any> {
return this.actions.pipe(
ofType<A>(actionType),
withLatestFrom(this.store),
pessimisticUpdate(opts)
);
}
/**
* See {@link optimisticUpdate} operator for more information.
*
* @deprecated Use the {@link optimisticUpdate} operator instead.
* The {@link DataPersistence} class will be removed in v15.
*/
optimisticUpdate<A extends Action = Action>(
actionType: string | ActionCreator,
opts: OptimisticUpdateOpts<[T], A>
): Observable<any> {
return this.actions.pipe(
ofType<A>(actionType),
withLatestFrom(this.store),
optimisticUpdate(opts)
);
}
/**
* See {@link fetch} operator for more information.
*
* @deprecated Use the {@link fetch} operator instead.
* The {@link DataPersistence} class will be removed in v15.
*/
fetch<A extends Action = Action>(
actionType: string | ActionCreator,
opts: FetchOpts<[T], A>
): Observable<any> {
return this.actions.pipe(
ofType<A>(actionType),
withLatestFrom(this.store),
fetch(opts)
);
}
/**
* See {@link navigation} operator for more information.
*
* @deprecated Use the {@link navigation} operator instead.
* The {@link DataPersistence} class will be removed in v15.
*/
navigation(
component: Type<any>,
opts: HandleNavigationOpts<[T]>
): Observable<any> {
return this.actions.pipe(
withLatestFrom(this.store),
navigation(component, opts)
);
}
}
function findSnapshot(
component: Type<any>,
s: ActivatedRouteSnapshot

View File

@ -1,16 +0,0 @@
import { ModuleWithProviders, NgModule } from '@angular/core';
import { DataPersistence } from './data-persistence';
/**
* @whatItDoes Provides services for enterprise Angular applications.
*
* See {@link DataPersistence} for more information.
*
* @deprecated Use the individual operators instead. Will be removed in v15.
*/
@NgModule({})
export class NxModule {
static forRoot(): ModuleWithProviders<NxModule> {
return { ngModule: NxModule, providers: [DataPersistence] };
}
}