Skip to content

allow component inputs to be readonly within signal store #4323

@ducin

Description

@ducin

Which @ngrx/* package(s) are relevant/related to the feature request?

signals

Information

The issue is inspired by this tweet. In short:

  • the OP has a component input() signal which they want signal store to react to
  • the OP found out there are existing 2 ways to do that:
    • effect / allowSignalWrites: true
    • rxMethod
  • in this very case, loadProductDetail seems to be an asynchronous operation, but let's abstract it away, let's assume it could be a synchronous one (which boils down to computed, essentially).

It bothers me, that ngrx signal store is signal-based first and foremost, and that the only 2 solutions are:

  • rxMethod-based -> signals themselves are capable of full-blown (synchronous) reactivity tithout the need of rx
  • effect/allowSignalWrites-based -> allowSignalWrites is both risky and developerPreview (effect, entirely, as for v17), my gut feeling we shouldn't have to reach out for it in such a simple usecase. Effect/signalWrites is a hack, especially when the component input already exists and is a building block that should be possible to compose further.

(in other words we could say that ngrx signal store is incapable of composing component inputs as for now)

I don't think the above would be the most fundamental usecase, though I think combining component Inputs and signal store would be quite common in the long run.

THE IDEA

What I'm thinking of is a way for signal store to include a computed which would be accepted from outside, e.g. apart from withComputed, there'd be withInputs (just made up the name).

This doesn't seem trivial from the API surface area, i.e.:

  • when injecting via inject(MyStore) there's no "syntactic place" to put additional parameters (which could include the hypothetical input signals). Moreover, store could be injected into e.g. services which don't have input signals
  • publishing an additional method on the store class e.g. MyStore.withInputs(inputs) seem to be even worse, because of breaking the well-designed composability which ngrx signal store achieved.
  • hypothetically a new injecting function injectStore could accept additional parameters, e.g. injectStore(StoreClass, { PARAMS }) where one of the params could be simply inputs (and uses native inject underneath). But that, unfortunately, adds another building block to the whole ecosystem which would be nice to avoid.

I'd be happy to provide a PR but, definitely, design work needs to be done first.

EXAMPLE SCENARIO

Let's say our scenario is:

  • the signal store includes it's own state, e.g. a collection of objects
  • the component has an input() signal which passes the chosen IDs which we want to filter and do some calculations on top of them
  • we want the store to do the (optional) filtering + calculations, e.g. within withComputed
  • whenever the chosen IDs change, store reacts to it. The store could accept a readonly signal and make the withComputed consume it/depend on it

last note

if anything is anyhow unclear I'm happy to explain further.

Again, as the component input() signal already exists and can be used, it feels wrong to me to either use effect/signalWrites or rxMethod.

Describe any alternatives/workarounds you're currently using

No response

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