0

Requirement

There is some (for arguments sake) “global” application state that I am interested in injecting into components.

Each candidate component should receive an immutable snapshot of the state as it existed at the time that its constructor was invoked (for absolute clarity, the state snapshot that is injected into each component’s constructor must not change when the global state changes).

Constraints

I cannot (and do not wish to) use a root-level service or global constant from which components request a state snapshot. Such a solution would require that a component must explicitly request a state snapshot (from the injected service or global constant) from within its constructor, because if it attempted to retrieve it later in its lifecycle, the state might have changed and no longer be relevant to it.

I want to avoid having to declare an injected service locally within each client component’s providers array. This is unnecessarily burdensome. Clients should be able to simply inject a type (or injection token) and receive a state snapshot.

Problem

Although an injection factory method seemed on the surface to be an obvious solution (it would copy the global state and return it to the injector, which would in turn pass it to the component’s constructor), the factory is only invoked once (for each level in the injection hierarchy for which a provider has been configured). I understand that this is by design, however I think that there is a good use-case for the functionality I have described.

What would potentially work is an injection factory implementation similar in concept to Angular pure and impure pipes, where a factory (or potentially any injection configuration) could be declared “impure”, which would result in a new instance being injected into every dependent component.

Surely there is a way to do this?

0

I would create a service that holds the state and that updates the state when needed.

Inject that service in the components.

The service contains a method that returns a copy of the current state, that method can be called in the components constructors og NgOnInit methods.

If you later find that you need some components to be able to react on updated states then you can make the service observable and only listen in those components that requires updates.

Services in Angular 2+ are shared between all components that have them injected.

  • Thanks for the input, Bent. The problem with that solution is that it invites usage patterns that break state consistency. The state that is injected into each component MUST be a snapshot of the global state as it was when the component's constructor was invoked. That state may change outside of the constructor, and delegating responsibility for retrieving state reliably and consistently to client components is not ideal. I am concluding that such a pattern is not currently possible to implement within Angular. – Bryce Marshall Nov 21 '18 at 17:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.