I'm cleaning up my angular2 project and for many reasons, I've decided to start with a seed. This one.
This seed uses HMR but I don't fully understand what is the purpose of that.
At the beginning, I was thinking that HMR was about dynamical loading and replacing component while the web app is running.
But since I've put my eyes on the app.service.ts
, I've got lost. Here is the code of this service :
import { Injectable } from '@angular/core';
import { HmrState } from 'angular2-hmr';
@Injectable()
export class AppState {
// @HmrState() is used by HMR to track the state of any object during a hot module replacement
@HmrState() _state = { };
constructor() {
}
// already return a clone of the current state
get state() {
return this._state = this._clone(this._state);
}
// never allow mutation
set state(value) {
throw new Error('do not mutate the `.state` directly');
}
get(prop?: any) {
// use our state getter for the clone
const state = this.state;
return state[prop] || state;
}
set(prop: string, value: any) {
// internally mutate our state
return this._state[prop] = value;
}
_clone(object) {
// simple object clone
return JSON.parse(JSON.stringify( object ));
}
}
I was thinking that service simply provides a space to store some data. After all, this is just an example.
But this line did confuse me: @HmrState() _state = { };
. Is this service using HMR to manage data that we can manage with this.appState.set('value', value);
(this is from the HomeComponent) like a little Redux's store (without actions, dispatcher, blabla) ?
What is the purpose of the decorator @HmrState()
here ?
Thanks.
When I had a first look at
angular2-hmr
I was surprised as well. I thought it is something like a hot swap, but it is not really one. At least from what I see when I use it.It looks like it always reloads the application regardless of the changes type. However it can restore the state of the swapped objects. The intention of
@HmrState()
is to restore the component's state when the application is reloaded.Let's take a look at a small example. We have a form with an input which is bound (with
ngModel
orformControl
) to some component's property:We type in some value, e.g. 'test123' and click the button. It works.
Then suddenly we realise: the log description is missing. So we go to our code and add it:
Then the component's code is changed, HMR replaces it and we realise that the
inputValue
is lost.To restore the value during the HMR process
angular2-hmr
needs some information about the object state before it was wiped out. Here the@HmrState()
comes into play: it points out to the state that should be restored. In other words to make the first code snippet work with HMR the following should be done:The state is now known to the HMR processor and it can use the state to restore our value. Now when we change the component code to:
it magically reloads our application and the inputValue's value is preserved.