Reputation: 93
I'm working with standalone Angular components and experimenting with the NgRx Component Store. I'm facing confusion regarding the correct way to inject the component store into a component. Here's how I've been providing the store in my component:
@Component({
selector: 'example-selector',
standalone: true,
providers: [ExampleStore],
templateUrl: './comparison-view.component.html',
styles: [],
imports: [
CommonModule
],
})
export class ExampleComponent implements OnInit {
...
}
However, I came across the provideComponentStore method in the NgRx documentation:
import { provideComponentStore } from '@ngrx/component-store';
@Component({
selector: 'example-selector',
standalone: true,
providers: [provideComponentStore(ExampleStore)],
templateUrl: './comparison-view.component.html',
styles: [],
imports: [
CommonModule
],
})
export class ExampleComponent implements OnInit {
...
}
Both methods seemed to work in my application, and I could utilize the store without any issues. What's the exact difference between these two approaches, and which one is recommended for my use case?
Using Version 16.x of @ngrx/store
Upvotes: 0
Views: 985
Reputation: 73
You should use provideComponentStore()
method if you are planning to use lifecycle hooks such as OnStoreInit
, OnStateInit
or OnDestroy
. See: https://ngrx.io/guide/component-store/lifecycle
Also, if you do not register your component store using provideComponentStore()
and you use one of the hooks, you will see warning in browser console. It's also mentioned in the docs:
If you implement the lifecycle hooks in the ComponentStore, and register it with providers without using provideComponentStore(), in development mode, a warning is logged to the browser console.
Upvotes: 1
Reputation: 54619
When in doubt, always check the source code !
export function provideComponentStore<T extends object>(
componentStoreClass: Type<ComponentStore<T>>
): Provider[] {
const CS_WITH_HOOKS = new InjectionToken<ComponentStore<T>>(
'@ngrx/component-store ComponentStore with Hooks'
);
return [
{ provide: CS_WITH_HOOKS, useClass: componentStoreClass },
{
provide: componentStoreClass,
useFactory: () => {
const componentStore = inject(CS_WITH_HOOKS);
// Set private property that CS has been provided with lifecycle hooks
componentStore['ɵhasProvider'] = true;
if (isOnStoreInitDefined(componentStore)) {
componentStore.ngrxOnStoreInit();
}
if (isOnStateInitDefined(componentStore)) {
componentStore.state$
.pipe(take(1))
.subscribe(() => componentStore.ngrxOnStateInit());
}
return componentStore;
},
},
];
As you can see, this method will run the lifecycle hooks defined on the ComponentStore (as mentioned in the docs).
Upvotes: 1