Skip to content

Commit

Permalink
fix(angular): generate ngrx code using rxjs operators from rxjs/opera…
Browse files Browse the repository at this point in the history
…tors when workspace has rxjs <7.2.0 (#15977)
  • Loading branch information
leosvelperez committed Mar 31, 2023
1 parent 6eca9b6 commit 77f2d0a
Show file tree
Hide file tree
Showing 16 changed files with 84 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -402,12 +402,10 @@ export const loadUsersFailure = createAction(
exports[`ngrx NgModule Syntax should generate the ngrx effects 1`] = `
"import { Injectable, inject } from '@angular/core';
import { createEffect, Actions, ofType } from '@ngrx/effects';
import { switchMap, catchError, of } from 'rxjs';
import * as UsersActions from './users.actions';
import * as UsersFeature from './users.reducer';
import { switchMap, catchError, of } from 'rxjs';
@Injectable()
export class UsersEffects {
private actions$ = inject(Actions);
Expand Down Expand Up @@ -756,12 +754,10 @@ export const appRoutes: Routes = [
exports[`ngrx angular v14 support should generate the ngrx effects using "inject" for versions >= 14.1.0 1`] = `
"import { Injectable, inject } from '@angular/core';
import { createEffect, Actions, ofType } from '@ngrx/effects';
import { switchMap, catchError, of } from 'rxjs';
import * as UsersActions from './users.actions';
import * as UsersFeature from './users.reducer';
import { switchMap, catchError, of } from 'rxjs';
@Injectable()
export class UsersEffects {
private actions$ = inject(Actions);
Expand Down Expand Up @@ -868,3 +864,29 @@ export class UsersFacade {
}
"
`;
exports[`ngrx rxjs v6 support should generate the ngrx effects using rxjs operators imported from "rxjs/operators" 1`] = `
"import { Injectable, inject } from '@angular/core';
import { createEffect, Actions, ofType } from '@ngrx/effects';
import { of } from 'rxjs';
import { switchMap, catchError } from 'rxjs/operators';
import * as UsersActions from './users.actions';
import * as UsersFeature from './users.reducer';
@Injectable()
export class UsersEffects {
private actions$ = inject(Actions);
init$ = createEffect(() =>
this.actions$.pipe(
ofType(UsersActions.initUsers),
switchMap(() => of(UsersActions.loadUsersSuccess({ users: [] }))),
catchError((error) => {
console.error('Error', error);
return of(UsersActions.loadUsersFailure({ error }));
})
)
);
}
"
`;
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Injectable, inject } from '@angular/core';
import { createEffect, Actions, ofType } from '@ngrx/effects';

import { createEffect, Actions, ofType } from '@ngrx/effects';<% if (!importFromOperators) { %>
import { switchMap, catchError, of } from 'rxjs';<% } else { %>
import { of } from 'rxjs';
import { switchMap, catchError } from 'rxjs/operators';<% } %>
import * as <%= className %>Actions from './<%= fileName %>.actions';
import * as <%= className %>Feature from './<%= fileName %>.reducer';

import {switchMap, catchError, of} from 'rxjs';

@Injectable()
export class <%= className %>Effects {
private actions$ = inject(Actions);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
import type { GeneratorCallback, Tree } from '@nrwl/devkit';
import { addDependenciesToPackageJson, readJson } from '@nrwl/devkit';
import { checkAndCleanWithSemver } from '@nrwl/devkit/src/utils/semver';
import { addDependenciesToPackageJson } from '@nrwl/devkit';
import { gte } from 'semver';
import { rxjsVersion as defaultRxjsVersion } from '../../../utils/versions';
import { versions } from '../../utils/version-utils';
import { NormalizedNgRxGeneratorOptions } from './normalize-options';

export function addNgRxToPackageJson(tree: Tree): GeneratorCallback {
let rxjsVersion: string;
try {
rxjsVersion = checkAndCleanWithSemver(
'rxjs',
readJson(tree, 'package.json').dependencies['rxjs']
);
} catch {
rxjsVersion = checkAndCleanWithSemver('rxjs', defaultRxjsVersion);
}

const jasmineMarblesVersion = gte(rxjsVersion, '7.0.0') ? '~0.9.1' : '~0.8.3';
export function addNgRxToPackageJson(
tree: Tree,
options: NormalizedNgRxGeneratorOptions
): GeneratorCallback {
const jasmineMarblesVersion = gte(options.rxjsVersion, '7.0.0')
? '~0.9.1'
: '~0.8.3';
const ngrxVersion = versions(tree).ngrxVersion;

return addDependenciesToPackageJson(
Expand Down
3 changes: 2 additions & 1 deletion packages/angular/src/generators/ngrx/lib/generate-files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ export function generateNgrxFilesFromTemplates(

generateFiles(
tree,
joinPathFragments(__dirname, '..', 'files', 'latest'),
joinPathFragments(__dirname, '..', 'files', 'base'),
options.parentDirectory,
{
...options,
...projectNames,
importFromOperators: lt(options.rxjsVersion, '7.2.0'),
tmpl: '',
}
);
Expand Down
19 changes: 17 additions & 2 deletions packages/angular/src/generators/ngrx/lib/normalize-options.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
import { names } from '@nrwl/devkit';
import type { NgRxGeneratorOptions } from '../schema';
import { names, readJson, Tree } from '@nrwl/devkit';
import { checkAndCleanWithSemver } from '@nrwl/devkit/src/utils/semver';
import { dirname } from 'path';
import { rxjsVersion as defaultRxjsVersion } from '../../../utils/versions';
import type { NgRxGeneratorOptions } from '../schema';

export type NormalizedNgRxGeneratorOptions = NgRxGeneratorOptions & {
parentDirectory: string;
rxjsVersion: string;
};

export function normalizeOptions(
tree: Tree,
options: NgRxGeneratorOptions
): NormalizedNgRxGeneratorOptions {
let rxjsVersion: string;
try {
rxjsVersion = checkAndCleanWithSemver(
'rxjs',
readJson(tree, 'package.json').dependencies['rxjs']
);
} catch {
rxjsVersion = checkAndCleanWithSemver('rxjs', defaultRxjsVersion);
}

return {
...options,
parentDirectory: options.module
Expand All @@ -18,5 +32,6 @@ export function normalizeOptions(
: undefined,
route: options.route === '' ? `''` : options.route ?? `''`,
directory: names(options.directory).fileName,
rxjsVersion,
};
}
22 changes: 22 additions & 0 deletions packages/angular/src/generators/ngrx/ngrx.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -803,4 +803,26 @@ describe('ngrx', () => {
);
});
});

describe('rxjs v6 support', () => {
beforeEach(async () => {
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
await generateTestApplication(tree, { name: 'myapp' });
devkit.updateJson(tree, 'package.json', (json) => ({
...json,
dependencies: {
...json.dependencies,
rxjs: '~6.6.7',
},
}));
});

it('should generate the ngrx effects using rxjs operators imported from "rxjs/operators"', async () => {
await ngrxGenerator(tree, defaultOptions);

expect(
tree.read('/apps/myapp/src/app/+state/users.effects.ts', 'utf-8')
).toMatchSnapshot();
});
});
});
4 changes: 2 additions & 2 deletions packages/angular/src/generators/ngrx/ngrx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export async function ngrxGenerator(
schema: NgRxGeneratorOptions
): Promise<GeneratorCallback> {
validateOptions(tree, schema);
const options = normalizeOptions(schema);
const options = normalizeOptions(tree, schema);

if (!options.minimal || !options.root) {
generateNgrxFilesFromTemplates(tree, options);
Expand All @@ -28,7 +28,7 @@ export async function ngrxGenerator(

let packageInstallationTask: GeneratorCallback = () => {};
if (!options.skipPackageJson) {
packageInstallationTask = addNgRxToPackageJson(tree);
packageInstallationTask = addNgRxToPackageJson(tree, options);
}

if (!options.skipFormat) {
Expand Down

0 comments on commit 77f2d0a

Please sign in to comment.