I have this code:
totalPrice = Object.entries(
buyTicketData.pricingAndInvoicingType ==
PricingAndInvoicingType.invoiceItems
? buyTicketData.invoiceItems
: buyTicketData.pricingOptions[startPaymentIn?.pricingOptionId]
.invoiceItems
).reduce((newObj, [key, val]) => {
(cumulativValue, ii) => {
const ret =
cumulativValue +
(val.quantity ?? startPaymentIn?.invoiceItems[key] ?? 0) *
parseInt(val.unitPrice);
return ret;
};
}, 0);
In my understanding preiousValue is a cumulativ value, and it could be different in type with currentValue. In my case previousValue is a number while current value is an array with a keyandvalue` fields.
But it does not work, something work, maybe whole approach is wrong. What do you think?
./pages/hu/buyTicket/[eventId].tsx:75:5
Type error: Type '[string, InvoiceItemData]' is not assignable to type 'string'.
73 | startPaymentIn?.pricingOptionId)
74 | ) {
> 75 | totalPrice = Object.entries(
| ^
76 | buyTicketData.pricingAndInvoicingType ==
77 | PricingAndInvoicingType.invoiceItems
78 | ? buyTicketData.invoiceItems
error Command failed with exit code 1.
Object.entries turns an object into a list of key-value pairs.
For example:
let invoiceItems = {
'key-1': 100,
'key-2': 200,
};
Object.entries(invoiceItems); // [['key-1', 100], ['key-2', 200]]
If you now want to reduce this list, the first two arguments of the reduce callback function will be:
an accumulator (if you want to calculate the sum of something, this will be a number)
each item of the list, in my example they are of type [string, number]
To build on my example, I could add all the values together:
let totalPrice = Object.entries(invoiceItems).reduce(
(cumulativeValue, [key, val]) => {
// in my case, key is a string and val is of type number
return cumulativeValue + val;
},
0 // the initial value
);
// totalPrice === 300
I hope this somewhat explains how the types come to be. To answer your question, I think your reducer is a bit messed up as there are 2 functions. To fix it, this should work:
.reduce(
(cumulativeValue, [key, val]) => {
const ret =
cumulativeValue +
(val.quantity ?? startPaymentIn?.invoiceItems[key] ?? 0) *
parseInt(val.unitPrice);
return ret;
},
0
);
I think you're not returning anything inside of reduce function. Reduce function needs return value, and that return value is passed to previousValue in next iteration. So it is accumulative in this point because it manipulates and returns data, use as next iteration's previousValue. So try to return something inside of it. Also, I think you're using typescript, so I recommend you to insert some type defs at reduce function.
Finally I figured out rather than reduce I need a simple for loop.