Reputation: 475
I want to rehydrate @ngrx/store
when page loads/bootstrap.
I saved previous state in browser's IndexedDB with @ngrx/db
and I want to retrive this information at INIT_ACTION
of my store.
To make this I see that exist the metaReducers
like:
export function indexedDBSyncReducer(reducer: ActionReducer<any>): ActionReducer<any> {
return function newReducer(state, action: any) {
if (action.type == 'INITIAL_STATE') {
// Read information to db and set nextState
}
const nextState = reducer(state, action);
return nextState;
};
}
The problem is that to retrive information from @ngrx/db
I need to have the contructor for access. like this.
The metaReducers
are pure function so, How can I inject the Database
provider to use it in my reducer?
Upvotes: 0
Views: 1807
Reputation: 1293
You can use managed classes with a method that return the reducer function:
@Injectable()
export class AccountReducerFactory {
// here you get your db access (or any managed service) injected
constructor(private dbService: DbService) {}
createReducer() {
return (state: AccountState, action: Action) => {
if(action.type === 'INITIAL_STATE') {
const initialState = this.dbService.readInitialState()
// do something with your initial state
}
}
}
}
Then you provide your reducer using an injection token (as documented here). Here is a simplified example for an 'account' feature module:
export const ACCOUNT_REDUCER_TOKEN = new InjectionToken<ActionReducer<Map<string, Account>>>('Account state reducer')
export function getAccountReducer(accountReducerFactory: AccountReducerFactory): ActionReducer<Map<string, Account>> {
// here you create a reducer function with access to other managed services
return accountReducerFactory.createReducer()
}
@NgModule({
imports: [
StoreModule.forFeature('account', ACCOUNT_REDUCER_TOKEN)
],
providers: [
{
provide: ACCOUNT_REDUCER_TOKEN,
// here your AccountReducerFactory class will be instantiated with its deps
deps: [AccountReducerFactory],
useFactory: getAccountReducer
}
]
})
export class AccountModule {
}
This answers how to access a service in an ngrx reducer. As for your original question, you will face another challenge which is harder to overcome: indexedDb is asynchronous, ngrx initialisation is not. I wrote a short blog post about that here.
Upvotes: 2