ngrx / platform

Reactive State for Angular
https://ngrx.io
Other
8.04k stars 1.98k forks source link

Computed signal from selectSignal stops reacting after a while #3955

Closed konuch closed 1 year ago

konuch commented 1 year ago

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

store

Minimal reproduction of the bug/regression with instructions

Keep incrementing the counter and see that computed signal stops reacting after a while: https://stackblitz.com/edit/ngrx-seed-dkg6ik?file=src%2Fapp%2Feffects%2Fcounter.effects.ts

Minimal reproduction of the bug/regression with instructions

I'd expect that computed signals that use selectSignal method keep working.

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

NgRx: 16.1.0 Angular: 16.1.4 Node: Browsers: Chrome latest OS: Windows 10

Other information

No response

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

markostanimirovic commented 1 year ago

Hi @konuch,

The Store.selectSignal method creates a new signal each time it is executed. To fix the problem, create the counter signal outside of computed and everything will work as expected:

class AppComponent {
  private readonly store = inject(Store);

+  readonly count = this.store.selectSignal(fromRoot.getCount);
+  readonly computedCount = computed(() => this.count());
-  readonly computedCount = computed(() =>
-    this.store.selectSignal(fromRoot.getConfig)()
-  );
}
markostanimirovic commented 1 year ago

Closing this issue in favor of https://github.com/angular/angular/issues/51055

simeyla commented 1 year ago

@markostanimirovic I'm the author of the issue you referenced. Thanks for referencing it.

I'm sure this is affecting many people without them even realizing and it's not always trivial or possible to factor out selectSignal calls.

Would love to hear your thoughts over at https://github.com/angular/angular/issues/51055 if you have any further insight about how people are using signals / ngrx with respect to this.

konuch commented 1 year ago

Hi @konuch,

The Store.selectSignal method creates a new signal each time it is executed. To fix the problem, create the counter signal outside of computed and everything will work as expected:

class AppComponent {
  private readonly store = inject(Store);

+  readonly count = this.store.selectSignal(fromRoot.getCount);
+  readonly computedCount = computed(() => this.count());
-  readonly computedCount = computed(() =>
-    this.store.selectSignal(fromRoot.getConfig)()
-  );
}

Thanks for the temporary solution how to come around this issue.