Skip to content

fix(signals): deprecate calling rxMethod/signalMethod outside injection context#5079

Merged
rainerhahnekamp merged 3 commits intongrx:mainfrom
david-shortman:fix/rxmethod-false-positive-warning
Feb 20, 2026
Merged

fix(signals): deprecate calling rxMethod/signalMethod outside injection context#5079
rainerhahnekamp merged 3 commits intongrx:mainfrom
david-shortman:fix/rxmethod-false-positive-warning

Conversation

@david-shortman
Copy link
Contributor

@david-shortman david-shortman commented Jan 30, 2026

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

[x] Bugfix
[ ] Feature
[ ] Code style update (formatting, local variables)
[ ] Refactoring (no functional changes, no api changes)
[ ] Build related changes
[ ] CI related changes
[ ] Documentation content changes
[ ] Other... Please describe:

What is the current behavior?

When rxMethod or signalMethod is called with a reactive input outside an injection context without an explicit injector, a warning about a "potential memory leak" is displayed. This warning had some false positives in common usage patterns.

Closes #4991

What is the new behavior?

The warning is replaced with a deprecation message. The goal is to eventually align with Angular's reactive primitives by requiring an injector when reactive methods are called outside an injection context.

Changes:

  • rxMethod and signalMethod: warning updated to deprecation notice
  • Docs: alert type changed from inform to warn with deprecation language
  • Tests: assertions updated to match new message, added child injection context coverage

Does this PR introduce a breaking change?

[ ] Yes
[x] No

This is a non-breaking change to a dev-mode warning message.

The rxMethod and signalMethod memory leak warning now only fires when
the source injector is a root or platform injector. Previously, the
warning fired any time a reactive input was passed outside an injection
context, even when the source injector (e.g. a component injector)
would properly handle cleanup.

Uses duck-typed access to Angular's internal R3Injector.scopes property
to detect root/platform injectors.

Closes ngrx#4991

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@netlify
Copy link

netlify bot commented Jan 30, 2026

Deploy Preview for ngrx-io ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit 72f53ea
🔍 Latest deploy log https://app.netlify.com/projects/ngrx-io/deploys/6998e2e9ab36a000075581df
😎 Deploy Preview https://deploy-preview-5079--ngrx-io.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@markostanimirovic
Copy link
Member

Hey @david-shortman 👋

Thanks for raising these PRs. I'm glad to see your PRs again!

I don't think we should show the warning only for root/platform injectors. In the following situation:

@Injectable()
export class ParentService {
  readonly parentMethod = rxMethod(...);
}

@Component({
  template: `
    @if (show()) { <child /> }
  `,
  providers: [ParentService],
})
export class ParentComponent {
  readonly show = signal(false);
}

@Component({ /* ... */ })
export class ChildComponent implements OnInit {
  readonly parentService = inject(ParentService);
  
  ngOnInit() {
    this.parentService.parentMethod(interval(2_000));
  }
}

The memory leak will happen when ChildComponent is destroyed, but a warning won't be displayed.

Another problem with this implementation is using the private injector.scope property that can potentially change in a non-major Angular version without a breaking change notice.

@david-shortman
Copy link
Contributor Author

david-shortman commented Feb 2, 2026

I'll see if I can detect this situation. Additionally, I can add testing that would catch a breaking change from Angular.

Glad to be looking at NgRx again. I was curious to look at older issues I had been involved with but with the fresh lens of researching and validating ideas with Claude Code.

@rainerhahnekamp
Copy link
Contributor

👋 Hey all. If we’re looking to make changes here, I’d actually propose going into the opposite direction: show a deprecation message instead of a warning.

In that sense, rxMethod would align much better with the other Angular signal-based functions like effect, linkedSignal, and the resource APIs.

@david-shortman
Copy link
Contributor Author

david-shortman commented Feb 3, 2026

👋 Hey all. If we’re looking to make changes here, I’d actually propose going into the opposite direction: show a deprecation message instead of a warning.

In that sense, rxMethod would align much better with the other Angular signal-based functions like effect, linkedSignal, and the resource APIs.

You're referring to requiring supplying the injection context explicitly in all cases, correct?

Although I like the stylishness of the context being implicitly loaded, and the slightly less boilerplate that comes with it, I would support either direction.

So you're saying that, like the other Angular signal functions, unless you call in an injection context like the constructor, then you must explicitly supply the intended injection context?

@rainerhahnekamp
Copy link
Contributor

So you're saying that, like the other Angular signal functions, unless you call in an injection context like the constructor, then you must explicitly supply the intended injection context?

Exactly.

My take here is that rxMethod's should follow the design of Angular's signal functions. So it is more the aspect of consistency.

@markostanimirovic
Copy link
Member

Hey @david-shortman,

Do you want to update this PR with the suggested deprecation message?

@netlify
Copy link

netlify bot commented Feb 18, 2026

Deploy Preview for ngrx-site-v21 ready!

Name Link
🔨 Latest commit 72f53ea
🔍 Latest deploy log https://app.netlify.com/projects/ngrx-site-v21/deploys/6998e2e903df7e0008f30b3a
😎 Deploy Preview https://deploy-preview-5079--ngrx-site-v21.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@david-shortman david-shortman force-pushed the fix/rxmethod-false-positive-warning branch 4 times, most recently from 910f727 to 08be3d6 Compare February 18, 2026 15:23
…outside injection context

Instead of warning only when the source injector is root (which uses
private Angular APIs and misses cases like child→parent leaks), warn
for all reactive calls outside an injection context without an explicit
injector. This aligns with Angular's pattern for effect(), linkedSignal(),
and resource(), and avoids reliance on internal R3Injector.scopes API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@david-shortman david-shortman force-pushed the fix/rxmethod-false-positive-warning branch from 08be3d6 to c0db4c3 Compare February 18, 2026 15:36
@david-shortman david-shortman changed the title fix(signals): only warn about memory leak when source injector is root fix(signals): deprecate calling rxMethod/signalMethod with reactive inputs outside injection context Feb 18, 2026
@david-shortman david-shortman changed the title fix(signals): deprecate calling rxMethod/signalMethod with reactive inputs outside injection context fix(signals): replace memory leak warning with deprecation for rxMethod/signalMethod calls outside injection context Feb 18, 2026
@david-shortman david-shortman changed the title fix(signals): replace memory leak warning with deprecation for rxMethod/signalMethod calls outside injection context fix(signals): deprecate calling rxMethod/signalMethod outside injection context Feb 18, 2026
@david-shortman
Copy link
Contributor Author

Hey @david-shortman,

Do you want to update this PR with the suggested deprecation message?

Yes; knowing that's the direction that multiple maintainers are good with, I've updated the PR to deprecate calling outside injection context.

Copy link
Member

@markostanimirovic markostanimirovic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks @david-shortman! 👑

Copy link
Contributor

@rainerhahnekamp rainerhahnekamp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well done Mr. @david-shortman 👍

@rainerhahnekamp rainerhahnekamp merged commit 0ea338f into ngrx:main Feb 20, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

rxMethod warning about memory leak when none is possible

3 participants