cleanup(angular): remove deprecated DataPersistence service and generator option to use it (#12236)
This commit is contained in:
parent
09c6ccb266
commit
b3676e8019
@ -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,
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
export {
|
||||
DataPersistence,
|
||||
fetch,
|
||||
navigation,
|
||||
optimisticUpdate,
|
||||
pessimisticUpdate,
|
||||
} from './src/runtime/nx/data-persistence';
|
||||
export { NxModule } from './src/runtime/nx/nx.module';
|
||||
|
||||
@ -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>
|
||||
) {}
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
||||
@ -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()
|
||||
],
|
||||
|
||||
@ -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) {}
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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',
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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] };
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user