Angular KeyValueDiffers vs IterableDiffers




Asked on September 26, 2019
What is difference between Angular KeyValueDiffers and IterableDiffers and what is their usability?



Replied on September 26, 2019
KeyValueDiffers and IterableDiffers are the Angular classes to know the changes in objects within the ngDoCheck() callback method. Angular uses KeyValueDiffers for NgClass, NgStyle and others, and IterableDiffers  is used for NgFor and others internally. ngDoCheck() is a callback method that performs change-detection, invoked after the default change-detector runs.

1. ngDoCheck() runs for every change in object.
2. Inside ngDoCheck(),  KeyValueDiffers finds the actual change in array and objects in array.
3. IterableDiffers is also used within ngDoCheck() but it checks only the changes in iterable objects such as array, list.
4. KeyValueDiffers can find the changes in array as well as changes in properties of objects in array where as IterableDiffers can only detect changes in array and not objects of array.

Example for KeyValueDiffers


  constructor(private kvDiffers: KeyValueDiffers) {
  }
  ngOnInit() {
    this.arrayDiffer = this.kvDiffers.find([]).create();

    this.empArray.forEach(emp => {
      this.empDifferMap[emp.id] = this.kvDiffers.find(emp).create();
      this.empMap[emp.id] = emp;
    })
  }
  ngDoCheck() {
    //Detect changes in array when item added or removed
    let empArrayChanges = this.arrayDiffer.diff(this.empArray);
    if (empArrayChanges) {
      console.log('... Array changes ...');
      this.changeLogs.push('... Array changes ...');      
      empArrayChanges.forEachAddedItem((record) => {
        let emp = record.currentValue;
        this.empDifferMap.set(emp.id, this.kvDiffers.find(emp).create());
        this.empMap.set(emp.id, emp);
        console.log('Added ' + emp.name);
        this.changeLogs.push('Added ' + emp.name);

      });
      empArrayChanges.forEachRemovedItem((record) => {
        let emp = record.previousValue;
        this.empDifferMap.delete(emp.id);
        this.empMap.delete(emp.id);
        console.log('Removed ' + emp.name);
        this.changeLogs.push('Removed ' + emp.name);
      });
    }

    //Detect changes in object inside array
    for (let [key, empDiffer] of this.empDifferMap) {
      let empChanges = empDiffer.diff(this.empMap.get(key));
      if (empChanges) {
        empChanges.forEachChangedItem(record => {
          console.log('--- Employee with id ' + key + ' updated ---');
          this.changeLogs.push('--- Employee with id ' + key + ' updated ---');
          console.log('Previous value: ' + record.previousValue);
          this.changeLogs.push('Previous value: ' + record.previousValue);
          console.log('Current value: ' + record.currentValue);
          this.changeLogs.push('Current value: ' + record.currentValue);
        });
      }
    }
  }

Example for IterableDiffers 


  constructor(private itrDiffers:IterableDiffers) {
  }
  ngOnInit() {
    this.empDiffer = this.itrDiffers.find([]).create(null);
  }
  ngDoCheck() {
  const changes = this.empDiffer.diff(this.empArray);
  if (changes) {
            changes.forEachAddedItem(item => console.log('added ', item));
           changes.forEachRemovedItem(item => console.log('removed ', item));
         }
  }



Write Answer











©2024 concretepage.com | Privacy Policy | Contact Us