Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

provideState cannot be used in standalone components #4234

Closed
1 of 2 tasks
wshager opened this issue Feb 6, 2024 · 9 comments
Closed
1 of 2 tasks

provideState cannot be used in standalone components #4234

wshager opened this issue Feb 6, 2024 · 9 comments

Comments

@wshager
Copy link

wshager commented Feb 6, 2024

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

store

Minimal reproduction of the bug/regression with instructions

@Component({
  // ...
  providers: [provideState({})]
})
// ...

Typescript compilation error: Type 'EnvironmentProviders' is not assignable to type 'Provider'

Expected behavior

No compilation error

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

Ngrx: 15.3, Angular: 15.2.9, Node: 20.2

Other information

No response

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

  • Yes
  • No
@brandonroberts
Copy link
Member

This is by design in Angular. You either have to use them at the application bootstrap level, or the route providers level. We use the ENVIRONMENT_INITIALIZER token from Angular to register the feature state. No such initializer is available in the component providers.

@wshager
Copy link
Author

wshager commented Feb 6, 2024

@brandonroberts A workaround is to import the feature state in an NgModule and import that module in the standalone component. That gave me the impression that there should be a simpler way.

@BenGrn
Copy link

BenGrn commented Apr 11, 2024

@brandonroberts A workaround is to import the feature state in an NgModule and import that module in the standalone component. That gave me the impression that there should be a simpler way.

@wshager Did this work within a standalone application or a module based one utilising standalone components only?

@hudzenko
Copy link

Hi, we are currently using this workaround with module import as well. Unfortunately..

The case: We have separate lazy loaded widgets which are represented as standalone components. Each component has some feature store and imports some shared feature stores and has no it's own route (as it not a page but a widget). Providing feature stores globally does not suits us as well because of lazy loading.

So it is really a problem that it is impossible to provide a feature store to a standalone component with no route.

We have also found some tricky workaround with createEnvironmentInjector, but not sure it is a good solution.

PS. Component store does not suits our needs because we have some shared feature stores (which unfortunately can not be moved to root lvl due to lazy loading requirement).

@rainerhahnekamp
Copy link
Contributor

@hudzenko I guess the only solution is to fallback to the component or the signal store. What speaks against having shared feature states with the global store (provideState) and using the component/signal store for your widgets?

@hudzenko
Copy link

@rainerhahnekamp Thanks for the answer!

The main issue is that we can not currently find a good place to register shared feature stores. We are trying to not to add them to "application bootstrap level" (to keep our specific feature like fully lazy loaded) and at the same time our components does not have any other single entry point (like a single specific route or let's say micro-frontend).

That is why we have a not really good workaround (but it works as ngrx does not register same state or effects twice): We import same FeatureStoreModule to different widget-components or route-components.

Well yeah, ideally is to move the shared things to global store (to the root lvl as there is no other shared entry point). And convert not shared state logic to components or signal store. But we need to negotiate making some of our logic as not lazy loaded :)

@rainerhahnekamp
Copy link
Contributor

and at the same time our components does not have any other single entry point

Ouch. That doesn't make it easier.

Have you considered moving your shared feature state to ngrx signals/component store? You have simple services, could provide them in root, and as long as no one calls that service, it will not activate itself.

Although I'm afraid that the service files will end up in the main bundle, that would probably be the easiest solution.

@wshager
Copy link
Author

wshager commented Jun 27, 2024 via email

@rtpHarry
Copy link
Contributor

rtpHarry commented Sep 8, 2024

This might not be related to the original issue, but this is the top google result for the error code.

In my scenario, the issue was that I was using angular elements, plus standalone components.

This meant I wasn't doing a normal bootstrap.

The solution was to add the providers in at the root level by editing the appConfig, configured in main.ts, instead of trying to pass them in at the "root" AppComponent via the standalone component providers bit.

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

No branches or pull requests

6 participants