Search code examples
javascriptarraysobjectobservers

How to Observe changes in an array of objects


Javascript now implements Object.observe and Array.observe, however I cannot seem to find a way to merge the functionality.

What I am trying to do is to have an array of objects. When any property of one of the objects changes, I would like to be notified.

Object.observe allows me to be notified when a property of a specific object changes.

Array.observe allows me to be notified when an array level change occurs.

Unless I specifically observe each element of an array, I have no way to know when a specific element property changes.

For example:

var model = [
  {
    data: 'Buy some Milk',
    completed: false
  },
  {
    data: 'Eat some Food',
    completed: false
  },
  {
    data: 'Sleep in a Bed',
    completed: false
  },
  {
    data: 'Make Love not War',
    completed: false
  }
];

Array.observe(model, function(changeRecords) {
  console.log('Array observe', changeRecords);
});

model[0].data = 'Teach Me to code';
model[1].completed = true;
model.splice(1,1);
model.push({data: "It's a new one!",completed: true});

gives a console output of:

Array observe [Object, Object]
  0: Object
    addedCount: 0
    index: 1
    object: Array[4]
    removed: Array[1]
    type: "splice"
    __proto__: Object
  1: Object
    addedCount: 1
    index: 3
    object: Array[4]
    removed: Array[0]
    type: "splice"
    __proto__: Object
length: 2
__proto__: Array[0]

These two notifications relate specifically to:

model.splice(1,1);

and

model.push({data: "It's a new one!",completed: true});

but completely ignore

model[0].data = 'Teach Me to code';

and

model[1].completed = true;

Is there a way to observe every change, no matter whether it is an array level or object level change?

I know there are libraries that may be able to do this for me, however I would like to understand how to implement this directly in my own code.


EDIT: OK, So it seems I wasn't missing any magic functionality, and the only true option is to observe the individual elements of the array.

So to expand upon the original question, what is the most efficient method of adapting arrays to handle element observations?


Solution

  • Array observe observes array changes! You need to observe each object inside Array too using Object.Observe!

    See this

          function ObserveMyArray(myArray){
           var arr=myArray||[];
              for(var i=0;i<arr.length;i++){
                var item=arr[i];
    
            Object.observe(item , function(changes){
    
              changes.forEach(function(change) {
                   console.log(change.type, change.name, change.oldValue);
               });
    
              });
             } 
           Array.observe(arr, function(changeRecords) {
             console.log('Array observe', changeRecords);
           });
            }