Utilizing Angular 8 and Ngrx 8 (just for context), I have a state service that controls the state of my view model. Within this service, there is a property called viewModel$ which is a behavior subject. Initially, when the service fetches its data, the viewModel$.next() function is invoked with the new view model value, simultaneously setting another property named originalValue to that same view model value. This process works as expected.
However, my intention was for the original value to remain unchanged so that if the user decides to revert changes, I can easily discard the updated view model and revert back to the original value. Unfortunately, each time the view model is updated, the originalValue property also gets modified – despite not being an observable. I suspect it has something to do with closures, but I lack the expertise to pinpoint the issue.
My main question here is: why is this unexpected behavior happening and how can I rectify it? How can I achieve the desired functionality of preserving the old data to enable reverting changes, without having to retrieve the data from the store again? Despite this workaround being viable, I am intrigued by what is causing the problem in the first place. Additionally, other components of the “Project” require simultaneous reversion, and I prefer not to incur the added time and effort of converting state models to view models if possible.
Below is the relevant code snippet:
In the state service,
Properties:
public viewModel$: BehaviorSubject<ProjectCoreViewModel>;
public viewModelLoaded$: BehaviorSubject<boolean> = new BehaviorSubject(false);
public originalValue: ProjectCoreViewModel;
public isPristine$: BehaviorSubject<boolean> = new BehaviorSubject(true);
private isInitialized = false;
Initial selection of data (via facade for retrieval from store):
public selectData() {
this.facade.getProjectCore()
.subscribe(core => this.fromStoreStateModel(core));
}
Conversion from state model to view model, followed by calling the updateViewModel$ method:
fromStoreStateModel(projectCore: ProjectCore) {
if (projectCore) {
const viewModel: ProjectCoreViewModel = {
// Data assignment
};
this.updateViewModel$(viewModel);
}
}
updateViewModel$ method:
updateViewModel$(value: ProjectCoreViewModel) {
if (value) {
// ViewModel check and initialization logic
}
else {
this.setLoadedStatus(false);
}
}
setOriginalValue method:
// Original value assignment logic
This piece in my component updates the view model:
// View model update logic