Skip to content

Commit 79c830c

Browse files
fix(effects): use source instance for ngrxOnRunEffects to retain context (#2401)
1 parent a0a336a commit 79c830c

File tree

2 files changed

+42
-15
lines changed

2 files changed

+42
-15
lines changed

modules/effects/spec/integration.spec.ts

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ import {
1414
EffectSources,
1515
Actions,
1616
} from '..';
17-
import { ofType, createEffect } from '../src';
18-
import { mapTo } from 'rxjs/operators';
17+
import { ofType, createEffect, OnRunEffects, EffectNotification } from '../src';
18+
import { mapTo, exhaustMap, tap } from 'rxjs/operators';
19+
import { Observable } from 'rxjs';
1920

2021
describe('NgRx Effects Integration spec', () => {
2122
it('throws if forRoot() is used more than once', (done: DoneFn) => {
@@ -27,8 +28,10 @@ describe('NgRx Effects Integration spec', () => {
2728
],
2829
});
2930

30-
let router: Router = TestBed.get(Router);
31-
const loader: SpyNgModuleFactoryLoader = TestBed.get(NgModuleFactoryLoader);
31+
let router: Router = TestBed.inject(Router);
32+
const loader: SpyNgModuleFactoryLoader = TestBed.inject(
33+
NgModuleFactoryLoader
34+
) as SpyNgModuleFactoryLoader;
3235

3336
loader.stubbedModules = { feature: FeatModuleWithForRoot };
3437
router.resetConfig([{ path: 'feature-path', loadChildren: 'feature' }]);
@@ -61,7 +64,7 @@ describe('NgRx Effects Integration spec', () => {
6164
EffectsModule.forRoot([EffectWithOnInitAndResponse]),
6265
],
6366
});
64-
TestBed.get(EffectSources);
67+
TestBed.inject(EffectSources);
6568

6669
expect(dispatchedActionsLog).toEqual([
6770
INIT,
@@ -91,7 +94,7 @@ describe('NgRx Effects Integration spec', () => {
9194
]),
9295
],
9396
});
94-
TestBed.get(EffectSources);
97+
TestBed.inject(EffectSources);
9598

9699
expect(dispatchedActionsLog).toEqual([
97100
INIT,
@@ -148,6 +151,7 @@ describe('NgRx Effects Integration spec', () => {
148151
dispatched: createDispatchedReducer(dispatchedActionsLog),
149152
}),
150153
EffectsModule.forRoot([
154+
EffectLoggerWithOnRunEffects,
151155
RootEffectWithInitAction,
152156
EffectWithOnInitAndResponse,
153157
RootEffectWithoutLifecycle,
@@ -158,7 +162,9 @@ describe('NgRx Effects Integration spec', () => {
158162
],
159163
});
160164

161-
const effectSources = TestBed.get(EffectSources) as EffectSources;
165+
const logger = TestBed.inject(EffectLoggerWithOnRunEffects);
166+
167+
const effectSources = TestBed.inject(EffectSources);
162168
effectSources.addEffects(
163169
new FeatEffectWithIdentifierAndInitAction('one')
164170
);
@@ -169,17 +175,17 @@ describe('NgRx Effects Integration spec', () => {
169175
new FeatEffectWithIdentifierAndInitAction('one')
170176
);
171177

172-
let router: Router = TestBed.get(Router);
173-
const loader: SpyNgModuleFactoryLoader = TestBed.get(
178+
let router: Router = TestBed.inject(Router);
179+
const loader: SpyNgModuleFactoryLoader = TestBed.inject(
174180
NgModuleFactoryLoader
175-
);
181+
) as SpyNgModuleFactoryLoader;
176182

177183
loader.stubbedModules = { feature: FeatModuleWithForFeature };
178184
router.resetConfig([{ path: 'feature-path', loadChildren: 'feature' }]);
179185

180186
await router.navigateByUrl('/feature-path');
181187

182-
expect(dispatchedActionsLog).toEqual([
188+
const expectedLog = [
183189
// first store init
184190
INIT,
185191

@@ -201,10 +207,32 @@ describe('NgRx Effects Integration spec', () => {
201207

202208
// from lazy loaded module
203209
'[FeatEffectFromLazyLoadedModuleWithInitAction]: INIT',
204-
]);
210+
];
211+
212+
// reducers should receive all actions
213+
expect(dispatchedActionsLog).toEqual(expectedLog);
214+
215+
// ngrxOnRunEffects should receive all actions except STORE_INIT
216+
expect(logger.actionsLog).toEqual(expectedLog.slice(1));
205217
});
206218
});
207219

220+
@Injectable()
221+
class EffectLoggerWithOnRunEffects implements OnRunEffects {
222+
actionsLog: string[] = [];
223+
224+
constructor(private actions$: Actions) {}
225+
226+
ngrxOnRunEffects(
227+
resolvedEffects$: Observable<EffectNotification>
228+
): Observable<EffectNotification> {
229+
return this.actions$.pipe(
230+
tap(action => this.actionsLog.push(action.type)),
231+
exhaustMap(() => resolvedEffects$)
232+
);
233+
}
234+
}
235+
208236
@Injectable()
209237
class EffectWithOnInitAndResponse implements OnInitEffects {
210238
ngrxOnInitEffects(): Action {

modules/effects/src/effect_sources.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,8 @@ function resolveEffectSource(
104104
effectsErrorHandler
105105
);
106106

107-
const source = getSourceForInstance(sourceInstance);
108-
if (isOnRunEffects(source)) {
109-
return source.ngrxOnRunEffects(mergedEffects$);
107+
if (isOnRunEffects(sourceInstance)) {
108+
return sourceInstance.ngrxOnRunEffects(mergedEffects$);
110109
}
111110

112111
return mergedEffects$;

0 commit comments

Comments
 (0)