Angular is awesome. And data binding, in particular, has been a game changer for developing modern web apps. Something changes somewhere and—magically—every part of your UI that needs to respond does so.
However, I’ve always struggled with one corner case: What if you’re binding to an array, and the change that occurs is that something gets added or removed, and you need to respond to the change programmatically (not just in your HTML template)?
Sounds weird? Here’s the example:
👉 In poketto.me, users can drag and drop files to upload
👉 None of the files may exceed a file size limit
👉 The total number of files may not exceed a user-specific limit
So my FileListComponent has to validate the entire array of files every time a file is added or removed.
🙋♂️ I can’t do all that validating in the HTML template
🙋♂️ I can’t rely on ngOnChanges, as this only fires when the reference to the array changes
🙋♂️ I can’t fully rely on ngDoCheck because I only want to validate the changed files (not all of them every time)
Here’s the solution:
In my component, I’m using a “differ”:
private differ: any;
I get the IterableDiffers injected via dependency injection:
constructor(private differs: IterableDiffers) { }
Then, in the ngDoCheck() lifecycle hook, I can diff the file array using the differ and work with the changes:
ngDoCheck() {
const changes = this.differ.diff(this.files);
if (changes) {
// ...
}
}
´´´