I have an object called productionSheet which contains details of a plastic bag. Dimensions and other information are stored inside productionSheet.bagDetails. When my app's backend receives the productionSheet object from the frontend, the data must be passed to a function that calculates the bag's weight and adds the result to the object before saving it in the database. However, this operation overwrites other data within the object itself. Let me explain:
Backend router
productionSheetsRouter.post("/", checkJwt, async (req, res) => {
try {
let newProductionSheet = new ProductionSheet(req.body);
newProductionSheet = calculateWeightSingleBag(newProductionSheet);
await newProductionSheet.save();
res.status(201).json(newProductionSheet);
} catch (error) {
console.error("Error in productionSheetsRouter.post:", error);
res.status(400).json({ message: "Bad Request" });
}
});
This is the calculateWeightSingleBag() function:
const calculateWeightSingleBag = (productionSheet) => {
const widthDevelopment =
Number(productionSheet.bagDetails.input.dimensions.width.value) +
Number(productionSheet.bagDetails.input.gussets.openSideGusset.value);
const heightDevelopment =
Number(productionSheet.bagDetails.input.dimensions.height.value) +
Number(productionSheet.bagDetails.input.flaps.upperFlapOpen.value) +
Number(productionSheet.bagDetails.input.flaps.zipFlap.value) +
Number(productionSheet.bagDetails.input.gussets.openBottomGusset.value) / 2;
const heightDevelopmentNet =
Number(productionSheet.bagDetails.input.dimensions.height.value) +
Number(productionSheet.bagDetails.input.flaps.upperFlapOpen.value) / 2 +
Number(productionSheet.bagDetails.input.flaps.zipFlap.value) +
Number(productionSheet.bagDetails.input.gussets.openBottomGusset.value) / 2;
const bareWeight = (
widthDevelopment *
heightDevelopment *
2 *
(Number(productionSheet.bagDetails.output.thickness.value) / 10000) *
Number(productionSheet.bagDetails.output.specificWeight.value)
).toFixed(2);
const netDieCutWeight = (
widthDevelopment *
heightDevelopmentNet *
2 *
(Number(productionSheet.bagDetails.output.thickness.value) / 10000) *
Number(productionSheet.bagDetails.output.specificWeight.value) *
(1 - Number(productionSheet.bagDetails.input.cutting.cuttingDie.value) / 100)
).toFixed(2);
console.log("Before bagweight: ", productionSheet.bagWeight);
productionSheet.bagWeight = {
input: {
...productionSheet.bagWeight.input,
},
output: {
...productionSheet.bagWeight.output,
bareWeight: { value: bareWeight, cost: false, unit: "g" },
netDieCutWeight: { value: netDieCutWeight, cost: false, unit: "g" },
},
};
console.log("After bagweight: ", productionSheet.bagWeight);
return productionSheet;
};
export default calculateWeightSingleBag;
I have this result from the console.log():
Before bagweight: {
input: { netDieCutWeight: { value: 0, cost: false, unit: 'g' } },
output: {
bareWeight: { value: 0, cost: false, unit: 'g' },
netDieCutWeight: { value: 0, cost: false, unit: 'g' },
netDieCutWeightWithAccessories: { value: 0, cost: false, unit: 'g' }
}
}
After bagweight: {
output: {
bareWeight: { value: 1.56, cost: false, unit: 'g' },
netDieCutWeight: { value: 1.47, cost: false, unit: 'g' }
}
}
After bagweight should be:
input: { netDieCutWeight: { value: 0, cost: false, unit: 'g' } },
output: {
bareWeight: { value: 1.56, cost: false, unit: 'g' },
netDieCutWeight: { value: 1.47, cost: false, unit: 'g' }
netDieCutWeightWithAccessories: { value: 0, cost: false, unit: 'g' }
}
}
Req.Body is:
const emptyProductionSheetBackEnd = {
userId: "",
information: {
input: {
customer: "",
itemCode: "",
description: "",
},
},
bagDetails: {
input: {
bagType: { value: "Zip bag", cost: false },
dimensions: {
width: { value: 10, cost: false, unit: "mm" },
height: { value: 15, cost: false, unit: "mm" },
},
gussets: {
openBottomGusset: { value: 0, cost: false, unit: "mm" },
openSideGusset: { value: 0, cost: false, unit: "mm" },
},
flaps: {
zipFlap: { value: 0, cost: false, unit: "mm" },
upperFlapOpen: { value: 2, cost: false, unit: "mm" },
},
cutting: {
cuttingDie: { value: 0, cost: false, unit: "mm" },
},
},
output: {
thickness: {
value: 50,
cost: false,
unit: "microns",
},
specificWeight: {
value: 0.92,
cost: false,
unit: "g/cm",
},
},
},
bagWeight: {
input: {
netDieCutWeight: { value: 0, cost: false, unit: "g" },
},
output: {
bareWeight: { value: 0, cost: false, unit: "g" },
netDieCutWeight: { value: 0, cost: false, unit: "g" },
netDieCutWeightWithAccessories: { value: 0, cost: false, unit: "g" },
},
},
};
I have an object called productionSheet which contains details of a plastic bag. Dimensions and other information are stored inside productionSheet.bagDetails. When my app's backend receives the productionSheet object from the frontend, the data must be passed to a function that calculates the bag's weight and adds the result to the object before saving it in the database. However, this operation overwrites other data within the object itself. Let me explain:
Backend router
productionSheetsRouter.post("/", checkJwt, async (req, res) => {
try {
let newProductionSheet = new ProductionSheet(req.body);
newProductionSheet = calculateWeightSingleBag(newProductionSheet);
await newProductionSheet.save();
res.status(201).json(newProductionSheet);
} catch (error) {
console.error("Error in productionSheetsRouter.post:", error);
res.status(400).json({ message: "Bad Request" });
}
});
This is the calculateWeightSingleBag() function:
const calculateWeightSingleBag = (productionSheet) => {
const widthDevelopment =
Number(productionSheet.bagDetails.input.dimensions.width.value) +
Number(productionSheet.bagDetails.input.gussets.openSideGusset.value);
const heightDevelopment =
Number(productionSheet.bagDetails.input.dimensions.height.value) +
Number(productionSheet.bagDetails.input.flaps.upperFlapOpen.value) +
Number(productionSheet.bagDetails.input.flaps.zipFlap.value) +
Number(productionSheet.bagDetails.input.gussets.openBottomGusset.value) / 2;
const heightDevelopmentNet =
Number(productionSheet.bagDetails.input.dimensions.height.value) +
Number(productionSheet.bagDetails.input.flaps.upperFlapOpen.value) / 2 +
Number(productionSheet.bagDetails.input.flaps.zipFlap.value) +
Number(productionSheet.bagDetails.input.gussets.openBottomGusset.value) / 2;
const bareWeight = (
widthDevelopment *
heightDevelopment *
2 *
(Number(productionSheet.bagDetails.output.thickness.value) / 10000) *
Number(productionSheet.bagDetails.output.specificWeight.value)
).toFixed(2);
const netDieCutWeight = (
widthDevelopment *
heightDevelopmentNet *
2 *
(Number(productionSheet.bagDetails.output.thickness.value) / 10000) *
Number(productionSheet.bagDetails.output.specificWeight.value) *
(1 - Number(productionSheet.bagDetails.input.cutting.cuttingDie.value) / 100)
).toFixed(2);
console.log("Before bagweight: ", productionSheet.bagWeight);
productionSheet.bagWeight = {
input: {
...productionSheet.bagWeight.input,
},
output: {
...productionSheet.bagWeight.output,
bareWeight: { value: bareWeight, cost: false, unit: "g" },
netDieCutWeight: { value: netDieCutWeight, cost: false, unit: "g" },
},
};
console.log("After bagweight: ", productionSheet.bagWeight);
return productionSheet;
};
export default calculateWeightSingleBag;
I have this result from the console.log():
Before bagweight: {
input: { netDieCutWeight: { value: 0, cost: false, unit: 'g' } },
output: {
bareWeight: { value: 0, cost: false, unit: 'g' },
netDieCutWeight: { value: 0, cost: false, unit: 'g' },
netDieCutWeightWithAccessories: { value: 0, cost: false, unit: 'g' }
}
}
After bagweight: {
output: {
bareWeight: { value: 1.56, cost: false, unit: 'g' },
netDieCutWeight: { value: 1.47, cost: false, unit: 'g' }
}
}
After bagweight should be:
input: { netDieCutWeight: { value: 0, cost: false, unit: 'g' } },
output: {
bareWeight: { value: 1.56, cost: false, unit: 'g' },
netDieCutWeight: { value: 1.47, cost: false, unit: 'g' }
netDieCutWeightWithAccessories: { value: 0, cost: false, unit: 'g' }
}
}
Req.Body is:
const emptyProductionSheetBackEnd = {
userId: "",
information: {
input: {
customer: "",
itemCode: "",
description: "",
},
},
bagDetails: {
input: {
bagType: { value: "Zip bag", cost: false },
dimensions: {
width: { value: 10, cost: false, unit: "mm" },
height: { value: 15, cost: false, unit: "mm" },
},
gussets: {
openBottomGusset: { value: 0, cost: false, unit: "mm" },
openSideGusset: { value: 0, cost: false, unit: "mm" },
},
flaps: {
zipFlap: { value: 0, cost: false, unit: "mm" },
upperFlapOpen: { value: 2, cost: false, unit: "mm" },
},
cutting: {
cuttingDie: { value: 0, cost: false, unit: "mm" },
},
},
output: {
thickness: {
value: 50,
cost: false,
unit: "microns",
},
specificWeight: {
value: 0.92,
cost: false,
unit: "g/cm",
},
},
},
bagWeight: {
input: {
netDieCutWeight: { value: 0, cost: false, unit: "g" },
},
output: {
bareWeight: { value: 0, cost: false, unit: "g" },
netDieCutWeight: { value: 0, cost: false, unit: "g" },
netDieCutWeightWithAccessories: { value: 0, cost: false, unit: "g" },
},
},
};
Share
Improve this question
edited Feb 4 at 8:37
Alessio Canna
asked Feb 3 at 19:46
Alessio CannaAlessio Canna
12 bronze badges
7
|
Show 2 more comments
1 Answer
Reset to default 3Make your life easier: refactor your code so you're not repeating the same thing a million times, so you can actually work with it and understand it at a glance.
It also makes it much easier to change something that needs changing. In this case, the way you added those new properties: just add them. Don't create a completely new object with destructured "identical content", just direct, plain JS property assignment.
// This *absolutely* doesn't need to be a const, just declare it as
// a function that you can load from whatever is your `utils` module.
function calculateSingleBagWeight(productionSheet) {
const { bagWeight, input, output } = productionSheet.bagDetails;
const { dimensions, cutting, gussets, flaps } = input;
// Get all these strings converted to numbers.
const [
width,
height,
cuttingDie,
openSideGusset,
openBottomGusset,
upperFlapOpen,
zipFlap,
thickness,
specificWeight,
] = [
dimensions.width,
dimensions.height,
cutting.cuttingDie,
gussets.openSideGusset,
gussets.openBottomGusset,
flaps.upperFlapOpen,
flaps.zipFlap,
output.thickness,
output.specificWeight,
].map(e => parseFloat(e.value));
// Do some basic math:
const widthDevelopment = width + openSideGusset;
const heightDevelopment = height + upperFlapOpen + zipFlap + openBottomGusset / 2;
const heightDevelopmentNet = height + upperFlapOpen / 2 + zipFlap + openBottomGusset / 2;
const commonFactor = widthDevelopment * 2 * thickness / 10000 * specificWeight;
const bareWeight = heightDevelopment * commonFactor;
const dieFactor = (1 - cuttingDie) / 100;
const netDieCutWeight = heightDevelopmentNet * commonFactor * dieFactor;
// If all you want is to add properties to `output`: do that.
// Only write code for what needs to happen. Anything else is
// just a place for bugs to hide.
// step 1: make sure "output" exists. If it does, this line does nothing.
bagWeight.output ??= {};
// step 2: just assign the property values you need.
// And note: never use .toFixed() until the absolute last moment.
// Which is here. Not in the calculations we did before.
bagWeight.output.bareWeight = {
value: bareWeight.toFixed(2),
cost: false,
unit: `g`
};
bagWeight.outputDieCutWeight = {
value: netDieCutWeight.toFixed(2),
cost: false,
unit: `g`
};
return productionSheet;
}
req.body
– search-learn Commented Feb 3 at 20:19toFixed()
,value
is a string value. This may be acceptable, but the log is lying:bagweight.output.bareWeight.value
will be"1.56"
not1.56
. UseNumber(value)
or the unary plus operator (+value
) to pass an actual number via JSON. – Heretic Monkey Commented Feb 3 at 21:13productionSheet
or a banana. This is also a problem with the way the code is written - the function to calculate bag weight has to know about a production sheet is. If you reduce the amount of code in the question, you'd probably realize what the problem was, and be able to make the code more readable/sustainable, as well. Recomment posting in codereview.stackexchange – Codebling Commented Feb 3 at 21:20