Skip to content

javascript pushing object to the array at for loop changes the front components

I’m trying to push different objects at each time, but it changes the front components while looping the for loop. Here is my code.

let responseArray = [];

const sendBatchRequest = async function (response) {
    try {
        console.log(`response: ${JSON.stringify(response)}`);
        if (responseArray.length < 9) {
            responseArray.push(response); // push 9 components
            console.log(`responseArray at if: ${JSON.stringify(responseArray)}`);
        } else {
            responseArray.push(response); // push last 10th component
            console.log(`responseArray at else: ${JSON.stringify(responseArray)}`);
            for (let i = 0; i < responseArray.length; i++) {
                console.log(`responseArray ${i} - ${JSON.stringify(responseArray[i])}`);
            }
            // do something...
            responseArray = []; // reset the array
        }
    } catch (err) {
        console.log(`sendBatchRequest err: ${err}`);
    }
}

const main = async function () {
    try {
        const result = {};
        for (let i = 0; i < 5; i++) {
            result.data = i;
            await sendBatchRequest(result);
        }
    } catch (err) {
        console.log(`main err: ${err}`);
    }
}

main();

And my result looks like this.

response: {"data":0}
responseArray at if: [{"data":0}]
response: {"data":1}
responseArray at if: [{"data":1},{"data":1}]
response: {"data":2}
responseArray at if: [{"data":2},{"data":2},{"data":2}]
response: {"data":3}
responseArray at if: [{"data":3},{"data":3},{"data":3},{"data":3}]
response: {"data":4}
responseArray at if: [{"data":4},{"data":4},{"data":4},{"data":4},{"data":4}]

I can’t understand why at 2th loop, responseArray[0] changes {"data":0} to {"data":1}. I want my responseArray looks like [{"data":0},{"data":1"},...]. What’s happening on Array.push(object) at javascript? And how could I get the result what I want?

Answer

It’s because you’re passing the result variable as a reference, everytime the result.data changes, so as the pushed items on the responseArray will be changed also.

So to avoid that. do this instead:

let responseArray = [];

const sendBatchRequest = async function (response) {
    try {
        console.log(`response: ${JSON.stringify(response)}`);
        if (responseArray.length < 9) {
            responseArray.push(response); // push 9 components
            console.log(`responseArray at if: ${JSON.stringify(responseArray)}`);
        } else {
            responseArray.push(response); // push last 10th component
            console.log(`responseArray at else: ${JSON.stringify(responseArray)}`);
            for (let i = 0; i < responseArray.length; i++) {
                console.log(`responseArray ${i} - ${JSON.stringify(responseArray[i])}`);
            }
            // do something...
            responseArray = []; // reset the array
        }
    } catch (err) {
        console.log(`sendBatchRequest err: ${err}`);
    }
}

const main = async function () {
    try {
        for (let i = 0; i < 5; i++) {
            const result = {data: i};  // Do this change
            await sendBatchRequest(result);
        }
    } catch (err) {
        console.log(`main err: ${err}`);
    }
}

main();