Last active
February 22, 2017 21:33
-
-
Save cmckni3/332627bc8b39d58c3014fda72d6f1c35 to your computer and use it in GitHub Desktop.
Angular 2 ngrx/store HMR
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'rxjs/add/operator/take'; | |
import { | |
Action, | |
ActionReducer, | |
combineReducers, | |
Store, | |
StoreModule | |
} from '@ngrx/store'; | |
import { compose } from '@ngrx/core/compose'; | |
// AppState is an interface custom to your application | |
type StoreType = { | |
state: AppState, | |
restoreInputValues: () => void, | |
disposeOldHosts: () => void | |
}; | |
// Reducer for setting the root STATE for HMR | |
const stateSetter: ActionReducer<any> = (reducer: ActionReducer<any>) => { | |
return (state, action ) => { | |
if (action.type === 'SET_ROOT_STATE') { | |
return action.payload; | |
} | |
return reducer(state, action); | |
}; | |
}; | |
const rootReducer = compose(stateSetter, combineReducers)({ | |
// Add your reducers here | |
}); | |
// ... | |
export class AppModule { | |
constructor(public appRef: ApplicationRef, private _store: Store<any>) {} | |
hmrOnInit(store: StoreType) { | |
if (!store || !store.state) return; | |
console.log('HMR store', JSON.stringify(store, null, 2)); | |
// set state | |
// restore state by dispatch a SET_ROOT_STATE action | |
if (store.state) { | |
this._store.dispatch(<Action>{ type: 'SET_ROOT_STATE', payload: store.state }); | |
} | |
// set input values | |
if ('restoreInputValues' in store) { | |
let restoreInputValues = store.restoreInputValues; | |
setTimeout(restoreInputValues); | |
} | |
this.appRef.tick(); | |
delete store.state; | |
delete store.restoreInputValues; | |
} | |
hmrOnDestroy(store: StoreType) { | |
const cmpLocation = this.appRef.components.map(cmp => cmp.location.nativeElement); | |
// save state | |
this._store.take(1).subscribe(s => store.state = s); | |
// recreate root elements | |
store.disposeOldHosts = createNewHosts(cmpLocation); | |
// save input values | |
store.restoreInputValues = createInputTransfer(); | |
// remove styles | |
removeNgStyles(); | |
} | |
hmrAfterDestroy(store: StoreType) { | |
// display new elements | |
store.disposeOldHosts(); | |
delete store.disposeOldHosts; | |
} | |
} |
oh it is my fault, I've forget to import:
import 'rxjs/add/operator/take';
@hyzhak I added the rxjs import for take. I snipped out some of the code to show relevant bits. I think take
was being imported globally.
I think you are also missing imports for "createNewHosts", "createInputTransfer", and "removeNgStyles".
Yes, I removed Angular and AngularClass/hmr imports for brevity.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for snippet, it is very helpful! Sadly I get error:
Because
this._store.take
is undefined.