简体   繁体   中英

Javascript array is not somehow mutated

I have an express server which I have GET and POST, and as original state, I have the following:

let orders = [
        {
            sum: 0,
            purchases: [
                {
                    id: 1,
                    contractId: 55,
                    value: 100,
                },
                {
                    id: 2,
                    contractId: 55,
                    value: -100,
                }
            ]
        }
    ]
    
    // this function is running on GET request
    export const getOrders = (req, res) => {
    reply.status(200).send(orders)
    }

export const addOrder = (req, res) => {
const newOrder = req.body
orders.map((order) => {
    const correspondingorder = order.purchases.find(
        (purshase) => purshase.contractId === newOrder.contractId
    )
    if (correspondingorder) {

        order.purchases.push(newOrder)
        order.sum += newOrder.value
    } else {
        const newValues = { sum: newOrder.value, purchases: Array(newOrder) }
        orders.push(newValues)
    }
}

}

My intention here is to search in the list of orders if the new added order ID is exist, if so, then add it to the list of corresponding purchases, otherwise, create a new object containing a sum and the new order, but whenever I try to add a new order with the same id then it add it to the found contractID PLUS creating a new object containing a sum and new order.

here is an example of what I get after my first POST and then GET:

[
    {
        "sum": 100,
        "purchases": [
            {
                "id": 1,
                "contractId": 55,
                "value": 100
            },
            {
                "id": 2,
                "contractId": 55,
                "value": -100
            },
            {
                "id": 3,
                "contractId": 55,
                "value": 100
            }
        ]
    }
]

then my second attempts of adding a different order with POST:

[
    {
        "sum": 100,
        "purchases": [
            {
                "id": 1,
                "contractId": 55,
                "value": 100
            },
            {
                "id": 2,
                "contractId": 55,
                "value": -100
            },
            {
                "id": 3,
                "contractId": 55,
                "value": 100
            }
        ]
    },
    {
        "sum": 100,
        "purchases": [
            {
                "id": 3,
                "contractId": 44,
                "value": 100
            }
        ]
    }
]

then another post and got this results:

[
    {
        "sum": 100,
        "purchases": [
            {
                "id": 1,
                "contractId": 55,
                "value": 100
            },
            {
                "id": 2,
                "contractId": 55,
                "value": -100
            },
            {
                "id": 3,
                "contractId": 55,
                "value": 100
            }
        ]
    },
    {
        "sum": 200,
        "purchases": [
            {
                "id": 3,
                "contractId": 44,
                "value": 100
            },
            {
                "id": 4,
                "contractId": 44,
                "value": 100
            }
        ]
    },
    {
        "sum": 100,
        "purchases": [
            {
                "id": 4,
                "contractId": 44,
                "value": 100
            }
        ]
    }
]

any idea why this weird behavior is happening?

This is because orders.map returns a new object and doesn't mutate the original, you can override the original with:

orders = orders.map((order) => {
        const correspondingorder = order.purchases.find(
            (purshase) => purshase.contractId === newOrder.contractId
        )
        if (correspondingorder) {
            order.purchases.push(newOrder)
            order.sum += newOrder.value
        } else {
            const newValues = { sum: newOrder.value, purchases: Array(newOrder) }
            orders.push(newValues)
        }
    }
}

But honestly, I don't recommend mutating Objects in this context, because more than 1 request can be reading/writing that variable.

If you really need to use this approach, use Array.forEach and reference the original object instead of map (that returns a new array and doesn't mutate the original one)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM