Thursday, July 27, 2017
NGRX Platform, redux
I have been using something similar undoables for an undo/redo function in my reducers. This implementation maintains the last array in memory, which would consume quite a few resources, so I rewrote it to keep the changed documents available for redo, and implemented effects to update the persistent storage. Worked fine in ngrx/store v2. And in ngrx/store v4 if I didn't use AOT. The feared Error: Error encountered resolving symbol values statically.
In my reducer definition I had code that looked like this:
export const reducers: ActionReducerMap = {
connection: fromConnections.reducer,
contactlist: undoable(fromContactList.reducer),
contactemails: undoable(fromContactEmail.reducer),
contactphones: undoable(fromContactPhone.reducer),
contactwebsite: undoable(fromContactWebsite.reducer),
};
undoable gets a reducer as a parameter and returns it. AOT doesn't like it.
So there are two solutions.
You can provide the reducers.
export const REDUCER_TOKEN = new InjectionToken>('Registered Reducers');
export const reducerProvider = [
{ provide: REDUCER_TOKEN, useValue: reducers },
];
export function undoableLayoutReducer(state: any, action: Action): fromLayout.State {
return undoable(fromLayout.reducer)(state, action);
}
export const reducers: ActionReducerMap = {
layout: undoableLayoutReducer,
};
which encapsulates the factory function in something that AOT likes. Right now this is required if you have a factory for your reducer in a feature store, as the forFeature doesn't as yet work with providers.
In my reducer definition I had code that looked like this:
export const reducers: ActionReducerMap
connection: fromConnections.reducer,
contactlist: undoable(fromContactList.reducer),
contactemails: undoable(fromContactEmail.reducer),
contactphones: undoable(fromContactPhone.reducer),
contactwebsite: undoable(fromContactWebsite.reducer),
};
undoable gets a reducer as a parameter and returns it. AOT doesn't like it.
So there are two solutions.
You can provide the reducers.
export const REDUCER_TOKEN = new InjectionToken
export const reducerProvider = [
{ provide: REDUCER_TOKEN, useValue: reducers },
];
creates a token and provider, then in your module some magic.
// WORKAROUND HERE
Object.assign(REDUCER_TOKEN, reducers);
// WORKAROUND HERE
Then import the StoreModule
imports: [
BrowserModule,
CommonModule,
...
StoreModule.forRoot(REDUCER_TOKEN),
],
providers: [
reducerProvider,
]
The Object.assign hack is necessary, it won't work without it, at least in v 4.0.1.
The second way is to
export function undoableLayoutReducer(state: any, action: Action): fromLayout.State {
return undoable(fromLayout.reducer)(state, action);
}
export const reducers: ActionReducerMap
layout: undoableLayoutReducer,
};
which encapsulates the factory function in something that AOT likes. Right now this is required if you have a factory for your reducer in a feature store, as the forFeature doesn't as yet work with providers.
Subscribe to Posts [Atom]