Skip to content

Commit a28175c

Browse files
fix(eslint-plugin): avoid-mapping-selectors don't report on ThisExpression (#3546)
Closes #3511
1 parent 9768551 commit a28175c

File tree

2 files changed

+83
-15
lines changed

2 files changed

+83
-15
lines changed

modules/eslint-plugin/spec/rules/avoid-mapping-selectors.spec.ts

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -118,27 +118,71 @@ export class CollectionService {
118118
import { Store } from '@ngrx/store'
119119
120120
class OkBecauseOfThis {
121-
foo$ = this.store.select(selectIsAuthenticated).pipe(
121+
storeSelect$ = this.store.select(selectIsAuthenticated).pipe(
122122
take(1),
123123
map((isAuthenticated: boolean) => (isAuthenticated ? true : this.router.parseUrl('/login'))),
124124
)
125125
126+
pipeSelect$ = this.store.pipe(
127+
select(selectIsAuthenticated),
128+
take(1),
129+
map((isAuthenticated: boolean) => (isAuthenticated ? true : this.router.parseUrl('/login'))),
130+
)
126131
127132
constructor(private store: Store) {}
128133
}`,
129134
`
130135
import { Store } from '@ngrx/store'
131136
132137
class OkBecauseOfEffect {
133-
foo$ = createEffect(() => {
134-
return this.store.select(selectObj).pipe(
135-
map((obj) => obj.prop),
136-
distinctUntilChanged(),
137-
map(() => anAction())
138-
)
139-
})
140-
141-
constructor(private store: Store) {}
138+
storeSelect$ = createEffect(() => {
139+
return this.store.select(selectObj).pipe(
140+
map((obj) => obj.prop),
141+
distinctUntilChanged(),
142+
map(() => anAction())
143+
)
144+
})
145+
146+
pipeSelect$ = createEffect(() => {
147+
return this.store.pipe(
148+
select(selectObj),
149+
map((obj) => obj.prop),
150+
distinctUntilChanged(),
151+
map(() => anAction())
152+
)
153+
})
154+
155+
constructor(private store: Store) {}
156+
}`,
157+
// https://github.com/ngrx/platform/issues/3511
158+
`
159+
import { Store } from '@ngrx/store'
160+
161+
class OkBecauseOfEffect {
162+
storeSelect$ = createEffect(() => {
163+
return this.store.select(selectObj).pipe(
164+
switchMap(() => this.service.something()),
165+
map((obj) => obj.prop),
166+
)
167+
})
168+
169+
pipeSelect$ = createEffect(() => {
170+
return this.store.pipe(
171+
select(selectObj),
172+
exhaustMap(() => this.service.something()),
173+
map((obj) => obj.prop),
174+
)
175+
})
176+
177+
somethingElse$ = createEffect(() => {
178+
return this.store.pipe(
179+
select(selectObj),
180+
customOperator(() => this.prop),
181+
map((obj) => obj.prop),
182+
)
183+
})
184+
185+
constructor(private store: Store, private service: Service) {}
142186
}`,
143187
];
144188

modules/eslint-plugin/src/rules/store/avoid-mapping-selectors.ts

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { createRule } from '../../rule-creator';
55
import {
66
asPattern,
77
getNgRxStores,
8+
isMemberExpression,
89
namedCallableExpression,
910
pipeExpression,
1011
} from '../../utils';
@@ -59,17 +60,40 @@ export default createRule<Options, MessageIds>({
5960
return false;
6061
}
6162

63+
let pipeHasThisExpression = false;
64+
65+
const selectorQuery = `:matches(${selectSelector}, ${pipeWithSelectAndMapSelector})`;
6266
return {
63-
[`:matches(${selectSelector}, ${pipeWithSelectAndMapSelector}) > CallExpression[callee.name='map']:not(:has(ThisExpression))`](
67+
[`${selectorQuery} > CallExpression:has(ThisExpression)`](
6468
node: TSESTree.CallExpression
6569
) {
70+
pipeHasThisExpression = true;
71+
},
72+
[`${selectorQuery}[callee.property.name=pipe]:exit`](
73+
node: TSESTree.CallExpression
74+
) {
75+
if (pipeHasThisExpression) {
76+
pipeHasThisExpression = false;
77+
return;
78+
}
79+
6680
if (isInCreateEffect(node)) {
6781
return;
6882
}
69-
context.report({
70-
node,
71-
messageId,
72-
});
83+
84+
const operators = node.arguments;
85+
const mapOperator = operators.find(
86+
(operator) =>
87+
isCallExpression(operator) &&
88+
isIdentifier(operator.callee) &&
89+
operator.callee.name === 'map'
90+
);
91+
if (mapOperator) {
92+
context.report({
93+
node: mapOperator,
94+
messageId,
95+
});
96+
}
7397
},
7498
};
7599
},

0 commit comments

Comments
 (0)