Search code examples
javascriptnode.jsarraysmodulejavascript-objects

global variable is not updated when changed value in another file nodejs


In nodejs, I try to update the global variable exported from another file and check the result again. The values of the variable in original file and imported file are different.

I run file test.js and check the result. The result of gDataChange in DataCommon.js and test.js is different although it is the same variable.

In DataCommon.js, I exported gDataChange variable

let gDataChange = [];

function printArray()
{
    console.log('DataCommon.js call ', gDataChange);
}

function setArray(lArray)
{
    gDataChange = [...lArray];
}

module.exports = {
    gDataChange,
    printArray,
    setArray
}

In test.js, I push some data into the global array and call function setArray to change it.

var { gDataChange, printArray, setArray} = require('../../res/DataCommon.js');

if (!gDataChange.length)
{
    gDataChange.push(1);
    gDataChange.push(2);
    gDataChange.push(1);
    gDataChange.push(3);
}

function testGlobalVar() {
    let newData = [...gDataChange];
    newData = newData.filter((number)=>{
        return number != 1;
    });
    setArray(newData);
}

testGlobalVar();

console.log('test.js call ', gDataChange);
printArray();

setTimeout(() => {
    console.log(gDataChange);
}, 10000);

enter image description here

If I used array.splice(), the gDataChange of 2 file are the same. But if I used array.filter() and re-assigned array like above, the gDataChange of 2 file are the different. I am not sure that gDataChange is created to the new one when I re-assigned with array.filter() because I cannot check the address of a variable in this case.


Solution

  • The Node.js module system is Singleton and module caching, the module system refers to the exact same file again and again. For example:

    counter.js

    let value = 0
    
    module.exports = {
      increment: () => value++,
      get: () => value,
    }
    

    app.js

    const counter1 = require(‘./counter.js’)
    const counter2 = require(‘./counter.js’)
    
    counter1.increment()
    counter1.increment()
    counter2.increment()
    
    console.log(counter1.get()) // prints 3
    console.log(counter2.get()) // also prints 3
    

    In your case, it is happening the same way. However, you are changing the reference of your array gDataChange. Chek the below code:

    let arr = [1, 2, 3, 4];
    const arr1 = arr.filter(x => x % 2 === 0); // this filter returns new array that refers to the new filtered data.
    
    console.log(arr1); // new array
    
    const arrOld = arr; // assigned reference of old array to new variable
    
    arr = arr1; // assigning filtered data reference to arr
    
    console.log(arr, arrOld); // you are seeing this in your code.

    So, the change in values is not because of node it is because you are changing the reference to objects. This is how JS objects works. Even when you assign the filter array values, you are creating new array.

    let gDataChange = [];
    
    function printArray()
    {
        console.log('DataCommon.js call ', gDataChange);
    }
    
    function setArray(lArray)
    {
        gDataChange = [...lArray]; // here a new array reference with filter values are assigned.
    // now if you change anything in the filter array it won't reflect here.
    }
    
    module.exports = {
        gDataChange,
        printArray,
        setArray
    }
    

    You can check how node modules are resolved.