Skip to content

Instantly share code, notes, and snippets.

@JurajMlich
Last active August 14, 2019 13:32
Show Gist options
  • Save JurajMlich/58ed66bb0843afc7ac969a90a77eceba to your computer and use it in GitHub Desktop.
Save JurajMlich/58ed66bb0843afc7ac969a90a77eceba to your computer and use it in GitHub Desktop.
import {BrowserModule} from '@angular/platform-browser';
import {ApplicationRef, NgModule, NgModuleFactoryLoader} from '@angular/core';
import {createInputTransfer, createNewHosts, removeNgStyles} from '@angularclass/hmr';
import {AppRoutingModule} from './app-routing.module';
import {AppComponent} from './app.component';
import {Store, StoreModule} from '@ngrx/store';
import {StoreDevtoolsModule} from '@ngrx/store-devtools';
import {environment} from '../environments/environment';
import {rootMetaReducers, rootReducers, RootState} from './root-store';
import {StoreRouterConnectingModule} from '@ngrx/router-store';
import {take} from 'rxjs/operators';
import {RouterExtService} from './misc/router.extension';
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule.withServerTransition({appId: 'app'}),,
StoreModule.forRoot(rootReducers, {metaReducers: rootMetaReducers}),
EffectsModule.forRoot([RootEffects]),
true || !environment.production ? StoreDevtoolsModule.instrument({
maxAge: 25
}) : [],
// StoreRouterConnectingModule.forRoot({stateKey: 'router'}),
SharedModule.forRoot(),
AppRoutingModule,
],
providers: [
RouterExtService,
],
bootstrap: [AppComponent]
})
export class AppModule {
constructor(
public appRef: ApplicationRef,
public store: Store<RootState.State>
) {
}
hmrOnInit(store) {
if (!store || !store.state) {
return;
}
console.log('HMR store', store);
console.log('store.state:', store.state);
this.store.dispatch({
type: 'SET_ROOT_STATE',
payload: store.state
});
if ('restoreInputValues' in store) {
const restore = store.restoreInputValues;
setTimeout(() => restore(), 500);
}
// change detection
this.appRef.tick();
delete store.state;
delete store.restoreInputValues;
}
hmrOnDestroy(store) {
const cmpLocation = this.appRef.components.map(cmp => cmp.location.nativeElement);
// recreate elements
store.disposeOldHosts = createNewHosts(cmpLocation);
// inject your AppStore and grab state then set it on store
this.store.pipe(take(1)).subscribe(s => store.state = s);
store.state = Object.assign({}, store.state);
// save input values
store.restoreInputValues = createInputTransfer();
// remove styles
removeNgStyles();
}
hmrAfterDestroy(store) {
// display new elements
store.disposeOldHosts();
delete store.disposeOldHosts;
// anything you need done the component is removed
}
}
@Prinsn
Copy link

Prinsn commented Aug 14, 2019 via email

@JurajMlich
Copy link
Author

Great to hear that, but ngrx is not part of native angular, so there's not much they can do about it, I'm afraid. But a guide on the ngrx website would be greatly appreciated, that I think we can definitely agree on.

@Prinsn
Copy link

Prinsn commented Aug 14, 2019

I was speaking more to the amount of hoops to jump through just for HMR.

Also, I think you have partially obfuscated code at import {rootMetaReducers, rootReducers, RootState} from './root-store'; as that's local code. I don't think you've exposed the RootState anywhere.

I have it working with an empty interface as per the default reducer generation, not sure if it requires anything beyond just an object.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment