I am creating normally table rows and columns when I am using the simple map function with the data shown below, that works just fine:
const tableRows = [
{
name: 'SickLeave difference',
januaryPayment: '-12000',
febrauaryPayment: '0',
},
{
name: 'Holiday difference',
januaryPayment: '10000',
febrauaryPayment: '25000',
},
{
name: 'Result',
januaryPayment: '0',
febrauaryPayment: '23000',
},
];
<Table headerTextCodes={headerTextCodes} allowFormattedHeader={false}>
{ tableRows.map(row => (
<TableRow>
<TableColumn>
{ row.name }
</TableColumn>
<TableColumn>
{ row.januaryPayment }
</TableColumn>
<TableColumn>
{ row.febrauaryPayment }
</TableColumn>
</TableRow>
))
}
</Table>
But, when I am trying to create table rows and columns where I am creating the data by first formatting the result that I am mocking currently as a backend response:
const result = {
periodFrom: '2018-05-01',
periodTo: '2018-07-31',
sumDifference: 17873,
periodsPerReceiver: [
{
receiverType: {
code: 'ARBG_PRIV',
name: null,
},
resultsPerMonth: [
{
from: '2018-05-01',
to: '2018-05-31',
resultPerField: [
{
fieldCode: {
code: 'SP',
name: null,
},
previouslyPayed: 0,
newAmount: 2662,
difference: 2662,
},
],
isNewPaymentPeriod: false,
},
{
from: '2018-06-01',
to: '2018-06-30',
resultPerField: [
{
fieldCode: {
code: 'FP',
name: null,
},
paid: 6899,
newAmount: 0,
difference: -6899,
},
],
isNewPaymentPeriod: false,
},
{
from: '2018-07-01',
to: '2018-07-31',
resultPerField: [
{
fieldCode: {
code: 'FP',
name: null,
},
paid: 0,
newAmount: 20012,
difference: 20012,
},
],
isNewPaymentPeriod: false,
},
],
},
{
receiverType: {
code: 'BRUKER',
name: null,
},
resultsPerMonth: [
{
from: '2018-05-01',
to: '2018-05-31',
resultPerField: [
{
fieldCode: {
code: 'FP',
name: null,
},
paid: 0,
newAmount: 0,
difference: 0,
},
],
isNewPaymentPeriod: false,
},
{
from: '2018-06-01',
to: '2018-06-30',
resultPerField: [
{
fieldCode: {
code: 'FP',
name: null,
},
paid: 0,
newAmount: 2098,
difference: 2098,
},
],
isNewPaymentPeriod: false,
},
{
from: '2018-07-01',
to: '2018-07-31',
resultPerField: [
{
fieldCode: {
code: 'FP',
name: null,
},
paid: 0,
newAmount: 0,
difference: 0,
},
],
isNewPaymentPeriod: false,
},
],
},
],
};
I have created this function to structure data in the way I could use it to create table and table rows later in the render function:
const resultPerReceiver = (receiver) => {
const receiverObject = {
receiver: receiver.receiverType,
fields: [],
};
receiver.resultsPerMonth.forEach((monthResult) => {
monthResult.resultPerFields.forEach((resultPerField) => {
const fieldExists = receiverObject.field.find(e => e.field.code === resultPerField.fieldCode.code);
if (fieldExists) {
fieldExists.rows.forEach((row) => {
const rowExists = row.resultPerMonth.find(e => e.from === monthResult.from);
if (!rowExists) {
const newAmount = {
from: monthResult.from,
to: monthResult.to,
amount: resultPerField.newAmount,
};
const paid = {
from: monthResult.from,
to: monthResult.to,
amount: resultPerField.paid,
};
const difference = {
from: monthResult.from,
to: monthResult.to,
amount: resultPerField.difference,
};
fieldExists.rows.find(e => e.name === 'newAmount').resultPerMonth.push(newAmount);
fieldExists.rows.find(e => e.name === 'paid').resultPerMonth.push(paid);
fieldExists.rows.find(e => e.name === 'difference').resultPerMonth.push(difference);
}
});
} else {
receiverObject.field.push({
field: resultPerField.fieldCode,
rows: [
{
name: 'newAmount',
resultPerMonth: [
{
from: monthResult.from,
to: monthResult.to,
amount: resultPerField.newAmount,
},
],
},
{
name: 'paid',
resultPerMonth: [
{
from: monthResult.from,
to: monthResult.to,
amount: resultPerField.paid,
},
],
},
{
name: 'difference',
resultPerMonth: [
{
from: monthResult.from,
to: monthResult.to,
amount: resultPerField.difference,
},
],
},
],
});
}
});
});
return receiverObject;
};
const formattedResult = result.periodsPerReceiver.map(receiver => resultPerReceiver(receiver));
This gives the result that looks something like this:
const formattedResult = [
{
receiver: {code: "ARBG_PRIV", name: null },
fields: [
{ field: { code: "SP", name: null },
rows: [
{name: "newAmount", resultPerMonth: [
{from: "2018-06-01", to: "2018-06-31", amount: 2662},
{from: "2018-07-01", to: "2018-07-31", amount: 2662}
]
},
{name: "paid", resultPerMonth: [
{from: "2018-06-01", to: "2018-06-31", amount: 2662},
{from: "2018-07-01", to: "2018-07-31", amount: 2662}
]
},
{name: "difference", resultPerMonth: [
{from: "2018-06-01", to: "2018-06-31", amount: 2662},
{from: "2018-07-01", to: "2018-07-31", amount: 2662}
]
}
]
},
{ field: { code: "FP", name: null },
rows: [
{name: "newAmount", resultPerMonth: [
{from: "2018-06-01", to: "2018-06-31", amount: 2662},
{from: "2018-07-01", to: "2018-07-31", amount: 2662}
]
},
{name: "paid", resultPerMonth: [
{from: "2018-06-01", to: "2018-06-31", amount: 2662},
{from: "2018-07-01", to: "2018-07-31", amount: 2662}
]
},
{name: "difference", resultPerMonth: [
{from: "2018-06-01", to: "2018-06-31", amount: 2662},
{from: "2018-07-01", to: "2018-07-31", amount: 2662}
]
}
]
},
]
},
{
receiver: {code: "BRUKER", name: null },
fields: [
{ field: { code: "SP", name: null },
rows: [
{name: "newAmount", resultPerMonth: [
{from: "2018-06-01", to: "2018-06-31", amount: 2662},
{from: "2018-07-01", to: "2018-07-31", amount: 2662}
]
},
{name: "paid", resultPerMonth: [
{from: "2018-06-01", to: "2018-06-31", amount: 2662},
{from: "2018-07-01", to: "2018-07-31", amount: 2662}
]
},
{name: "difference", resultPerMonth: [
{from: "2018-06-01", to: "2018-06-31", amount: 2662},
{from: "2018-07-01", to: "2018-07-31", amount: 2662}
]
}
]
},
{ field: { code: "FP", name: null },
rows: [
{name: "newAmount", resultPerMonth: [
{from: "2018-06-01", to: "2018-06-31", amount: 2662},
{from: "2018-07-01", to: "2018-07-31", amount: 2662}
]
},
{name: "paid", resultPerMonth: [
{from: "2018-06-01", to: "2018-06-31", amount: 2662},
{from: "2018-07-01", to: "2018-07-31", amount: 2662}
]
},
{name: "difference", resultPerMonth: [
{from: "2018-06-01", to: "2018-06-31", amount: 2662},
{from: "2018-07-01", to: "2018-07-31", amount: 2662}
]
}
]
},
]
},
]
Then, I am trying to render this result from the function like this in the render function:
<div className={styles.table}>
{
formattedResult.map(reciever => (
<Table>
{ reciever.fields.map(field => field.rows.map(row => (
<TableRow>
<TableColumn>
<Image
tabIndex="0"
className={styles.expandButton}
src={arrowDownImageUrl}
altCode="Timeline.openData"
/>
{ row.name }
</TableColumn>
{ row.resultPerMonth.map(month => (
<TableColumn>
{ month.amount }
</TableColumn>
))}
</TableRow>
)))}
</Table>
))}
</div>
But, when I try to do it like that, I get an error:
Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports. in tbody (created by Table)
I have checked all the imports in the component, and I am importing them right, because this error is not happening when I am rendering the simple data shown above. I have no idea why is this happening in the latter case, what am I doing wrong?
Here you can see the sandbox for it.
children && children.length ...