Inner function does not return changes to variable assigned in outer function

Tags: , ,



I am attempting to modify the masterCounter variable within the timeKeyAdditionCheck function. Within the timeKeyAdditionCheck function, I successfully assign a value to masterCounter, but this change is not reflected within the scope of getEventsWithTime. When timeKeyAdditionCheck is complete, the value of masterCounter returns to null.

What changes do I need to make with timeKeyAdditionCheck function?

let masterCounter = null;
let userTracker = {}; 

let timeKeyAdditionCheck = ('hour') => {
    assert((range == 'minute' || range == 'hour'), "In calcArrayof... range value needs to equal 'minute' or 'hours'")
    
    if (masterCounter == null) {
        masterCounter = [{timerange: event.timestamp, totalusercount: 0, totalvalidatorcount: 0, totaletherdeposited: 0}]
    }
    if (event.timestamp > (masterCounter[masterCounter.length - 1] + 3599)) {
        
            let differenceInTime = event.timestamp - (masterCounter[masterCounter.length - 1] + 3599);
            let timeKeysNeeded = Math.ceil(differenceInTime / 3600);
        
            i = 0;
            while (i < timeKeysNeeded) {
                
                let newEntry = masterCounter[masterCounter.length - 1];
                newEntry.timerange = newEntry.timerange + 3600;
                masterCounter.push(newEntry);
                i++;
            }
        }
}
(async () => {
    let events = await getEventsWithTime(3085928,3089928);
    
    for (event of events) {
        timeKeyAdditionCheck('hour');
        checkNewUsers();
        addValidatorsAndEth();    
    }

    convertToCsv(masterCounter)
    console.log(masterCounter)
  })()

Answer

The reason I wasn’t getting the expected output for masterCounter was because, in the timeKeyAdditionCheckfunction, I thought I was making a copy of the object in the masterCounter array, but I actually created a reference instead. Here is the moment in my code when I unintentionally created a reference instead of a copy:

let newEntry = masterCounter[masterCounter.length - 1];

When I thought I was adding a unique object to the array, I was instead adding the reference to that same object at the end of the array.

I fixed it using the following code:

while (i < timeKeysNeeded) {
                
   let lastObjectRef = masterCounter[masterCounter.length - 1];
   let newEntry = Object.assign({}, lastObjectRef)
   newEntry.timerange = newEntry.timerange + 60;
   masterCounter.push(newEntry);
   i++;
}

I used Object.assign() to create a copy of the last object in the array instead of creating another reference.



Source: stackoverflow