javascriptjqueryarraysjsobject

Change value of dynamically added js object


I have an array with some predefined data

var data = [
    {amount:20, speed:100},
    {amount:40, speed:50}
];

I am then adding data to the above array

function addMore() {
    data = appendObjTo(data, {amount: 1500,speed:100});
}

function appendObjTo(thatArray, newObj) {
    const frozenObj = Object.freeze(newObj);
    return Object.freeze(thatArray.concat(frozenObj));
}

The data is being added fine, but for some reason, i am unable to change the value of the new data

function runData() {
    perSec = 0;
    $.each(data, function( key, value ) {
        perSecCalc = Math.round(value.speed/60);
        perSec += perSecCalc;
        // Below line works only for predefined objects, but not objects from "addMore()"
        data[key].amount = value.amount-perSec;
    });

    setTimeout(function() {
        runData();
    },1000);
}

While the predefined object in "var data" is being changed, the dynamically added data from "addMore" does not change.

How come the new data is not changing ?

Update: See this fiddle


Solution

  • You are using Object.freeze in your appendObjTo function. The definition of Object.freeze - Object.freeze().

    Since the frozenObj is created using Object.freeze(), the values are not allowed to change. Also, you are not getting any error on console. JS doesn't show error w/o strict mode enabled. I have modified the fiddle to include strict mode, and you can see that it throws and error when you do data[key].amount = value.amount-perSec;. I have also attached a fiddle to play with the Object.freeze() method, and you can experiment by yourself.

    Modified fiddle

    JS

    (function () {
    
    "use strict";
    
    var data = [
        {amount:20, speed:100}
    ];
    
    
    function runData() {
        var perSec = 0;
        $.each(data, function( key, value ) {
            var perSecCalc = Math.round(value.speed/60);
            perSec += perSecCalc;
            // Below line works only for predefined objects, but not objects from "addMore()"
            data[key].amount = value.amount-perSec;
            $('#test').prepend(data[key].amount+'<br>');
        });
    
        setTimeout(function() {
            runData();
        },1000);
    }
    
    function appendObjTo(thatArray, newObj) {
      const frozenObj = Object.freeze(newObj);
      return Object.freeze(thatArray.concat(frozenObj));
    }
    
    function addMore() {
        data = appendObjTo(data, {amount: 1500,speed:100});
    }
    
    setTimeout(function() { addMore(); },1500);
    
    runData();
    
    
    })();
    

    Object.freeze fiddle

    var arr = [10, 20, 30];
    console.log(arr);
    
    arr = Object.freeze(arr.concat([40, 50]));
    console.log(arr);
    
    arr[3] = 80;
    console.log(arr); // doesn't change
    
    // arr.push(60); // error, cannot add property 5, object is not extensible
    
    arr = Object.freeze(arr.concat([{ x: 100 }]));
    console.log(arr);
    
    arr[5].x = 200;
    console.log(arr); // changes, as Object.freeze only locks the first level values.