0

I'm facing a bit of a weird situation and I can't spot the cause. I'm my server update order endpoint, I can either receive an orderState or an updatedOrder to update MongoDB record var { orderState, updatedOrder } = req.body;. As I'll be modifying updatedOrder in a for loop to update MongoDB, I also assign the received updatedOrder to a constant to be passed later on to Neo4j to do same updates and create relationships, as const modifiedOrder = req.body.updatedOrder; .

With an if/else statement I either update MongoDB Order record state parameter or the entire Order record. In the second case, when updatedOrder.cart item state property is found to be 'Refund requested', and accordingly to the property isPromotion to be true or false I first update Product and Promotion records, then update updatedOrder cart item state value to Refunded, in the mentioned for loop.

Then after the for loop I update the Order record with the updated updatedOrder.

The problem is that after the first loop modifiedOrder is also updated, so when sent to Neo4j cart item state is not 'Refund requested' but 'Refunded'.

How can it be that const modifiedOrder value is changed when modifying var updatedOrder? Even dough they get the initial value from req.body.updatedOrder a const should keep the first assigned value right?

Can you spot what I'm doing wrong?

var { orderState, updatedOrder } = req.body; const modifiedOrder = req.body.updatedOrder; console.log( '1> Mongoose updatedOrder received modifiedOrder.cart is', modifiedOrder.cart ); // correct if (orderState) { ... } else if (updatedOrder) { for (var i = 0; i < updatedOrder.cart.length; i++) { console.log( `LOOP> Mongoose updatedOrder before loop ${i} modifiedOrder.cart is ${modifiedOrder.cart}` ); // at 1st loop (i = 0) CORRECT 1st item state is "Refund requested" // at second loop (i = 1) WRONG 1st item state is now "Refunded" var cartItem = JSON.parse(updatedOrder.cart[i]); if (cartItem.state == 'Refund requested') { if (cartItem.isPromotion == false) { await Product.findByIdAndUpdate( cartItem.id, { $inc: { soldQuantity: -1, availableQuantity: 1 }, }, { session: session, new: true, }, null ) .clone() .exec() .then((result) => { console.log( 'Mongoose Order.updateOrder / Product.update Inventory updated successfully for product:', result.id ); if (result != null) { cartItem.state = 'Refunded'; totalRefundAmount += result.price; } else { cartItem.state = 'Not refunded'; } return; }) .catch((error) => { if (error) { console.log( 'Mongoose Order.updateOrder / Product.update error: ', error ); cartItem.state = 'Not refunded'; throw error; } }); } else if (cartItem.isPromotion == true) { await Promotion.findByIdAndUpdate( cartItem.id, { $inc: { soldQuantity: -1, availableQuantity: 1 }, }, { session: session, new: true, } ) .clone() .exec() .then((result) => { if (result != null) { totalRefundAmount += result.price; cartItem.state = 'Refunded'; console.log( 'Mongoose Order.updateOrder / Promotion.update Inventory updated successfully for promotion:', result ); } else { cartItem.state = 'Not refunded'; } return; }) .catch((error) => { if (error) { console.log( 'Mongoose Order.updateOrder / Promotion.update error: ', error ); cartItem.state = 'Not refunded'; throw error; } }); } } updatedOrder.cart[i] = JSON.stringify(cartItem); } ... } 

before 1st loop 1st item is "Refund requested":

LOOP> Mongoose updatedOrder before loop 0 modifiedOrder.cart is {"createdOnDate":1638894572905,"name":"testProduct","brand":"someBrand","price":12,"description":"description","category":"Safety and locks","city":"Bologna","region":"Emilia-Romagna","country":"Italy","vendor":"testShop","vendorId":"OrderTestShop","barcode":"some","imageUrl":"https://firebasestorage.googleapis.com/v0/b/fix-it-b4b00.appspot.com/o/Products%2F61af8bec02edbe24ce034963?alt=media&token=a891dc05-407e-43d2-ab2b-0f49226249a9","fullImages":[],"thumbNails":[],"minimumStock":10,"availableQuantity":10,"soldQuantity":0,"isPromotion":false,"totalRating":0,"ratings":0,"_id":"636a0c9e8145999716d71de2","createdAt":"2022-11-08T08:00:30.399Z","updatedAt":"2022-11-08T08:00:30.399Z","__v":0,"averageRating":0,"id":"636a0c9e8145999716d71de2","isRecommendation":true,"state":"Refund requested"},{"createdOnDate":1638894572905,"productId":"636a0c9e8145999716d71de2","name":"testPromotion","brand":"someBrand","price":12,"description":"new description","category":"Safety and locks","city":"Bologna","region":"Emilia-Romagna","country":"Italy","vendor":"testShop","vendorId":"OrderTestShop","barcode":"some","imageUrl":"https://firebasestorage.googleapis.com/v0/b/fix-it-b4b00.appspot.com/o/Products%2F61af8bec02edbe24ce034963?alt=media&token=a891dc05-407e-43d2-ab2b-0f49226249a9","fullImages":[],"thumbNails":[],"minimumStock":10,"availableQuantity":10,"soldQuantity":0,"isPromotion":true,"totalRating":0,"ratings":0,"_id":"636a0c9e8145999716d71de4","createdAt":"2022-11-08T08:00:30.467Z","updatedAt":"2022-11-08T08:00:30.467Z","__v":0,"averageRating":0,"id":"636a0c9e8145999716d71de4","isRecommendation":true,"state":"Bought"} 

after first loop 1st item is "Refunded":

LOOP> Mongoose updatedOrder before loop 1 modifiedOrder.cart is {"createdOnDate":1638894572905,"name":"testProduct","brand":"someBrand","price":12,"description":"description","category":"Safety and locks","city":"Bologna","region":"Emilia-Romagna","country":"Italy","vendor":"testShop","vendorId":"OrderTestShop","barcode":"some","imageUrl":"https://firebasestorage.googleapis.com/v0/b/fix-it-b4b00.appspot.com/o/Products%2F61af8bec02edbe24ce034963?alt=media&token=a891dc05-407e-43d2-ab2b-0f49226249a9","fullImages":[],"thumbNails":[],"minimumStock":10,"availableQuantity":10,"soldQuantity":0,"isPromotion":false,"totalRating":0,"ratings":0,"_id":"636a0c9e8145999716d71de2","createdAt":"2022-11-08T08:00:30.399Z","updatedAt":"2022-11-08T08:00:30.399Z","__v":0,"averageRating":0,"id":"636a0c9e8145999716d71de2","isRecommendation":true,"state":"Refunded"},{"createdOnDate":1638894572905,"productId":"636a0c9e8145999716d71de2","name":"testPromotion","brand":"someBrand","price":12,"description":"new description","category":"Safety and locks","city":"Bologna","region":"Emilia-Romagna","country":"Italy","vendor":"testShop","vendorId":"OrderTestShop","barcode":"some","imageUrl":"https://firebasestorage.googleapis.com/v0/b/fix-it-b4b00.appspot.com/o/Products%2F61af8bec02edbe24ce034963?alt=media&token=a891dc05-407e-43d2-ab2b-0f49226249a9","fullImages":[],"thumbNails":[],"minimumStock":10,"availableQuantity":10,"soldQuantity":0,"isPromotion":true,"totalRating":0,"ratings":0,"_id":"636a0c9e8145999716d71de4","createdAt":"2022-11-08T08:00:30.467Z","updatedAt":"2022-11-08T08:00:30.467Z","__v":0,"averageRating":0,"id":"636a0c9e8145999716d71de4","isRecommendation":true,"state":"Bought"} `` 
0

1 Answer 1

1

const obj = { key: 'value1' }; const objShallowCopy = obj; const objDeepCopy = JSON.parse(JSON.stringify(obj)); obj.key = 'value2'; console.log('objShallowCopy: ', objShallowCopy); console.log('objDeepCopy: ', objDeepCopy);

Sign up to request clarification or add additional context in comments.

3 Comments

HI and thanks for answering. yeap the const in js still gets me at times lol. Still just to make sure, I'm changing the value of updatedOrder which changes req.body.updatedOrder as well, thus modifiedOrder gets changed as well. Correct ?? I thought about it, but thought that req.body.updatedOrder wouldn't get modified so ruled it out. Should have known better.. I do now! lol
Correct, updatedOrder and modifiedOrder and req.body.updatedOrder all reference (point to) the same location in memory (in this case, an "order" object). Declaring something with const ensure that what value/object it references cannot be changed but it but it doesn't prevent changes to the values within that referenced object.
To phrase it differently, const creates an immutable binding, not an immutable value.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.