Skip to content

Commit e21df19

Browse files
fix(signals): run onDestroy outside of injection context (#4200)
1 parent 1b5458d commit e21df19

File tree

2 files changed

+27
-19
lines changed

2 files changed

+27
-19
lines changed

modules/signals/spec/signal-store.spec.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,8 @@ describe('signalStore', () => {
268268
expect(message).toBe('onDestroy');
269269
});
270270

271+
// FIX: injection context will be provided for `onDestroy` in a separate PR
272+
// see https://github.com/ngrx/platform/pull/4196#issuecomment-1875228588
271273
it('executes hooks in injection context', () => {
272274
const messages: string[] = [];
273275
const TOKEN = new InjectionToken('TOKEN', {
@@ -281,7 +283,7 @@ describe('signalStore', () => {
281283
messages.push('onInit');
282284
},
283285
onDestroy() {
284-
inject(TOKEN);
286+
// inject(TOKEN);
285287
messages.push('onDestroy');
286288
},
287289
})
@@ -293,6 +295,22 @@ describe('signalStore', () => {
293295
destroy();
294296
expect(messages).toEqual(['onInit', 'onDestroy']);
295297
});
298+
299+
it('succeeds with onDestroy and providedIn: root', () => {
300+
const messages: string[] = [];
301+
const Store = signalStore(
302+
{ providedIn: 'root' },
303+
withHooks({
304+
onDestroy() {
305+
messages.push('ending...');
306+
},
307+
})
308+
);
309+
TestBed.inject(Store);
310+
TestBed.resetTestEnvironment();
311+
312+
expect(messages).toEqual(['ending...']);
313+
});
296314
});
297315

298316
describe('composition', () => {

modules/signals/src/signal-store.ts

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,13 @@
1-
import {
2-
DestroyRef,
3-
inject,
4-
Injectable,
5-
Injector,
6-
runInInjectionContext,
7-
signal,
8-
Type,
9-
} from '@angular/core';
1+
import { DestroyRef, inject, Injectable, signal, Type } from '@angular/core';
102
import { STATE_SIGNAL, StateSignal } from './state-signal';
113
import {
124
EmptyFeatureResult,
135
InnerSignalStore,
146
MergeFeatureResults,
15-
SignalStoreProps,
167
SignalStoreConfig,
178
SignalStoreFeature,
189
SignalStoreFeatureResult,
10+
SignalStoreProps,
1911
} from './signal-store-models';
2012
import { Prettify } from './ts-helpers';
2113

@@ -325,16 +317,14 @@ export function signalStore(
325317
(this as any)[key] = props[key];
326318
}
327319

328-
if (hooks.onInit) {
329-
hooks.onInit();
330-
}
320+
const { onInit, onDestroy } = hooks;
331321

332-
if (hooks.onDestroy) {
333-
const injector = inject(Injector);
322+
if (onInit) {
323+
onInit();
324+
}
334325

335-
inject(DestroyRef).onDestroy(() => {
336-
runInInjectionContext(injector, hooks.onDestroy!);
337-
});
326+
if (onDestroy) {
327+
inject(DestroyRef).onDestroy(onDestroy);
338328
}
339329
}
340330
}

0 commit comments

Comments
 (0)