@InjectStore decorator
@InjectStore decorator is responsible for injecting store and state variables into actions class
First parameter is Path to state
if added between single quotes '' it counts as absolute path
@InjectStore('todos/items/1')if added in array [], final path will be merged with path passed from parent. e.g: if parent component path is
todosand child component path isfilterso marking child component with@InjectStore(['filter'])will result path like['todos', 'filter']. Do not forget to pass parent path from parent to child by adding to child component markup<todos-filter [statePath]="statePath"></todos-filter>if state is part of the list,
stateIndexparam should be passed from the parent component and new path will look like:['items', '${stateIndex}'] -> ['todos', 'items', '0]stateIndexcan be an array of indexes so state path can have multiple${stateIndex}:@InjectSore(['${stateIndex}', 'some_other_path', '${stateIndex}'])there can be use-cases when actions can be shared because of identical states keeping in different locations. In this case there can be anonymous function passed as a first parameter:
@InjectStore((currentPath: string[]) => {
return currentPath.indexOf('search') >= 0
? ['entities', '${stateIndex}']
: ['${stateIndex}'];
})Second Parameter: initialState
initialStateYou can provide an initial state object as the second parameter. This is useful when the state slice requires default values:
@InjectStore('todos/sports-todos', {
name: '',
description: ''
})
export class TodosActions {
store!: Store<TodosState>;
}Note: Often in larger applications, you cannot define all pieces of state upfront. Many pieces should be created "on the fly". For this scenario, you can provide a function or object that returns the initial state.
Initial State as a Function
Instead of a static object, you can pass a function as the initial state. The function is executed each time the store is created, allowing dynamic or context-aware defaults:
@InjectStore('todos/sports-todos', () => ({
name: '',
description: '',
createdAt: new Date() // dynamic initial value
}))
export class TodosActions {
store!: Store<TodosState>;
}This is particularly useful when:
The initial state depends on runtime values (like the current date, user info, or configuration).
You need fresh instances of objects or arrays to avoid shared references.
Third Parameter: Debug Mode
Optionally, you can enable debug mode by passing a boolean as the third parameter:
@InjectStore('todos/sports-todos', { name: '', description: '' }, { debug: true })
export class TodosActions {
store!: Store<TodosState>;
}debug = true→ Logs warnings for missing state paths.debug = false→ Silently ignores path checks (default behavior).
Third Parameter: isPersistentStore
Each time when component creation new actions are created (if component was destroyed). Upon new action creation state, within that path, is seeded with initialValue. However there are situations when you would want to keep this state untouched / persistent. For this reason you can use isPersistentStore: true; This way upon first creation state will get initial value but all subsequent creations of those actions will return existing state.
This maybe very usefull when you want to use state mutations in not related components.
@InjectStore('todos/sports-todos', { name: '', description: '' }, { isPersistentStore: true })
export class TodosActions {
store!: Store<TodosState>;
}Example: Dynamic State Creation
@InjectStore(
(currentPath, stateIndex) => `users/${stateIndex}/profile`,
() => ({
firstName: '',
lastName: '',
lastLogin: new Date()
})
)
export class UserProfileActions {
store!: Store<UserProfileState>;
}Here, the store path is dynamically computed based on the stateIndex, and the initial state is generated at runtime.
Last updated
Was this helpful?