Skip to content

rxMethod warning about memory leak when none is possible #4991

@david-shortman

Description

@david-shortman

Which @ngrx/* package(s) are the source of the bug?

signals

Minimal reproduction of the bug/regression with instructions

rxMethod warns about possible memory leaks in a simple scenario:

@Component({
  template: `<button (click)=example() />`
})
export class ExampleComponent {
  someMethod = rxMethod<string>(pipe(tap(console.log)));

  value = signal('arbitrary');

  example() {
    this.someMethod(this.value);
  }
}

When clicking the button, you'll get a warning in dev mode that starts with "@ngrx/signals/rxjs-interop: The reactive method was called outside the injection context with a signal or observable."

Expected behavior

There should not be a warning in this case. The source injector is used as the instance injector in the case where there is not a caller injector. It seems like the warning should be implemented like:

const instanceInjector = config?.injector ?? callerInjector ?? sourceInjector;

if (
  typeof ngDevMode !== 'undefined' &&
  ngDevMode &&
  instanceInjector === undefined
) {
  console.warn(
    '@ngrx/signals/rxjs-interop: The reactive method was called outside',
    'the injection context with a signal or observable. This may lead to',
    'a memory leak. Make sure to call it within the injection context',
    '(e.g. in a constructor or field initializer) or pass an injector',
    'explicitly via the config parameter.\n\nFor more information, see:',
    'https://ngrx.io/guide/signals/rxjs-integration#reactive-methods-and-injector-hierarchies'
  );
}

Versions of NgRx, Angular, Node, affected browser(s) and operating system(s)

Latest version 20.0.1

Other information

The warning appears to be overly cautious about RxMethods defined in scopes that are larger than the components in which they are used. I think that leads to unnecessary behavior which is always providing the injector even though it's unnecessary. I'm interested to figure out an alternative to improve the warning case (like comparing to the root injector?) or suppressing it in a tactful way.

IMO, the magic of rxMethod seamlessly handling ending subscriptions based on its declaration context is muddied by this warning that encourages always explicitly declaring an injection context when not called in an explicit injection context.

I would be willing to submit a PR to fix this issue

  • Yes
  • No

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions