please. I have a cycle with fiance balances. It's an array of objects like:
export const balances = [
type: types.outgoing,
date: 20220410,
amount: 282.12,
category: categories.installments,
source: 'Debit account',
destination: 'Leasing company',
},
{
type: types.income,
date: 20220413,
amount: 1385.3,
category: categories.job,
source: 'My employeer',
destination: 'Debit account',
},
...
]
etc...
As you can see, I have a categories there which means that I have in cycle every transaction in balances
and I must create separate category for each of them with total amount for each category, count of items in category and with detailed transactions for each category. I'm using array.forEach()
cycle:
balances.forEach((balance) => {
// Checking if category already exists in my array of categories
let categoryIndex = categories.findIndex((category) => category.category === balance.category)
// Create details of transaction
let transactionDetail = {
date: balance.date,
amount: balance.amount,
source: balance.source,
destination: balance.destination,
}
// If category already exists, just calculate total and add new object into array details
if (categoryIndex !== -1) {
console.log([categories[categoryIndex].details])
categories[categoryIndex] = {
type: balance.type,
category: balance.category,
amount: categories[categoryIndex].amount + balance.amount,
count: (categories[categoryIndex].count += 1),
// This row is wrong. I cannot use this
details: [categories[categoryIndex].details].push(transactionDetail),
}
} else {
// If category doesn't yet exists, we must create a first values in this category
categories.push({
type: balance.type,
category: balance.category,
amount: balance.amount,
count: 1,
details: [transactionDetail],
})
}
}
But the row
details: [categories[categoryIndex].details].push(transactionDetail)
doesn't work properly. Probably the reason is, that I have sometimes Object as tyopeof
result and sometimes undefined
Row console.log([categories[categoryIndex].details])
sometimes output:
// Output for
// console.log([categories[categoryIndex].details])
[Array(1)]0: Array(1)
0: {date: 20220414, amount: 410, source: 'xxx', destination: 'yyy'}
length: 1[[Prototype]]:
Array(0)length: 1
[[Prototype]]: Array(0)
[2]
0: 2
length: 1
[[Prototype]]: Array(0)
Any hiths how can add object transactionDetail
as a next in existing array? Thank you very much for any advice.
I don't understand. I can concat string if category already exists, add numbers but I cannot add an next object into array of objects.
EDIT: Just changed transaction
to trasactionDetail
in explanation.
I found several errors in your latter block and have corrected them; let me explain the changes I've made.
In the line you marked as wrong, you were putting brackets around the values for some reason. Categories.details
is presumably an array of TransactionDetail
, so you don't need to further nest it here. However, if you push into an array, that returns with the number of objects in the array, so when you did this in that line, details
would ultimately always be populated with a number. Rather, in my version, I split out the existing category you pulled via index as existing
and simply push the value to its details
array. This also just cleans up the top half of your condition since one need only reference the properties from the existing object to match against the new values in a cleaner way.
You were using 1(categories[categoryIndex].count += 1)
to increase the count. But, you're also setting precisely that object here, so this isn't a good practice. Rather, set the values you intend to use here and commit it all to the categories
array as one thing, instead of a mismatch of some values setting here, some set differently. I corrected this to a mere existing.count + 1
.
Here's your updated code in full then:
balances.forEach((balance) => {
// Checking if category already exists in my array of categories
let categoryIndex = categories.findIndex(category => category.category === balance.category);
// Create details of transaction
let transactionDetail = {
date: balance.date,
amount: balance.amount,
source: balance.source,
destination: balance.destination,
};
// If category already exists, just calculate total and add new object into array details
if (categoryIndex !== -1) {
const existing = categories[categoryIndex];
existing.details.push(transactionDetail);
categories[categoryIndex] = {
type: balance.type,
category: balance.category,
amount: existing.amount + balance.amount,
count: existing.count + 1,
details: existing.details
};
} else {
// If category doesn't yet exists, we must create a first values in this category
categories.push({
type: balance.type,
category: balance.category,
amount: balance.amount,
count: 1,
details: [transactionDetail],
});
}
});