I have a form for which I've got a js object as model. I want to detect a change in the object, to inform the user of the need to save.
To achieve this, I currently using KeyValueDiffers. It does also detect every change, as wanted. Although I have an unwanted effect.
The form is an own component and I'll set the object to modify over an @Input() which calls a init() method that also initializes the KeyValueDiffers with the new object.
After initialize the KeyValueDiffers I immediately get a change notification, although there was no change to the object that I used to initialize the differ yet. Why could this be? I'm clueless...
export class MetadataDetailComponent implements DoCheck {
constructor(private differs: KeyValueDiffers) { }
unsavedChanges: boolean = false;
differ: any;
metadata: Metadata;
orgMetadata: Metadata;
@Input()
set setMetadata(metadata: Metadata) {
this.init(metadata);
}
private init(metadata: Metadata) {
this.differ = undefined;
if (this.metadata && this.unsavedChanges) {
console.log('unsaved changes!!')
}
//Do different init stuff
this.orgMetadata = metadata;
this.metadata = new Metadata(metadata.name, metadata.description, metadata.id, metadata.state, metadata.type, metadata.script);
this.differ = this.differs.find(this.orgMetadata).create(null);
this.unsavedChanges = false;
}
ngDoCheck() {
if (this.differ) {
var changes = this.differ.diff(this.metadata);
if (changes) {
this.unsavedChanges = true;
console.log('metadata has changed!');
}
}
}
}
EDIT
This is the change event I'm getting

It seems like this is the change from null to the object. But why am I getting this change when I'm already initializing the KeyValueDiffers with the object?
I don't know if this solves your specific problem. But we had issues with KeyValueDiffer having "null" as the previous value on the first diff after things get going after ngOnInit. I've combed the internet and found no real answer on this, so we "solved" it by initializing the differ like so
or perhaps for your specific case
Note that create doesn't take an argument anymore in Angular 6+