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
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).