I have objects in the array. one of these objects references another template.
I want the price of the data in the reference template to be multiplied by the number in the array, and I want the result to be written to the total.
const debt = new Schema({
name: {
type: String,
required: true,
},
medicine: [{
data: {
type: Schema.Types.ObjectId,
ref: 'Medicine',
},
quantity: {
type: Number,
default: 1
}
}],
total: {
type: Schema.Types.Decimal128,
default: 0,
},
status: {
type: String,
required: true,
},
createdAt: {
type: Date,
default: Date.now,
},
});
const medicine = new Schema({
name: {
type: String,
unique: true,
required: true,
},
price: {
type: Schema.Types.Decimal128,
required: true,
},
medicineType: {
type: String,
required: true,
},
description: {
type: String,
required: true,
trim: true,
},
image: {
type: String,
},
createdAt: {
type: Date,
default: Date.now,
},
});
When we create data from the two templates above, the result is as follows.
{
name: 'John Doe',
no: '87102621880',
status: 'debtor',
note: 'not paid',
medicine: [
{ data: '624e0b9533533f3a31e3dc73', quantity: 2 },
{ data: '624e0b3633533f3a31e3dc6a', quantity: 3 }
],
total: 0
}
In the above result, the total value is zero, but I want it like this.
total = data.price * medicine.quantity
I want to do this operation inside the pre method, is it possible or is there another way?
I hope I have been able to explain, if there is more than one value in the medicine array, all of them (data.price * medicine.quantity)
should do the same and transfer them to the total value.
CodePudding user response:
You can define mongoose middleware to run pre/post some actions in the schema.
debtSchema.post('find',(results)=>{//do whatever you want here, it'll run every time you're querying by the 'find' method and you have access to the results})
Here's link to the official docs
CodePudding user response:
use Array.prototype.reduce()
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
const a = {
name: 'John Doe',
no: '87102621880',
status: 'debtor',
note: 'not paid',
price: 5,
medicine: [
{ data: '624e0b9533533f3a31e3dc73', quantity: 2, price: 5 },
{ data: '624e0b9533533f3a31e3dc73', quantity: 1, price: 3 },
{ data: '624e0b3633533f3a31e3dc6a', quantity: 3, price: 6 },
],
total: 0,
}
console.log(
a.medicine.reduce(
(previousValue, currentValue) =>
previousValue currentValue.quantity * currentValue.price,
0,
),
)
// if price is in different object
console.log(
a.medicine.reduce(
(previousValue, currentValue) =>
previousValue currentValue.quantity * a.price,
0,
),
)
// or just get count and then multiply by price
console.log(
a.medicine.reduce(
(previousValue, currentValue) =>
previousValue currentValue.quantity,
0,
) * a.price,
)
Edit: eddited mistake in snipper where it was adding instead of multiplying