let records = {
2018: {
Jan: {
records: [{
id: 123,
date: '01-Jan-2018',
amount: 300,
type: 'expense'
}],
totalExpenses: 300,
totalIncome: 0
},
Feb: {
records: [{
id: 234,
date: '01-Jan-2019',
description: 'Syabas',
amount: 100,
type: 'income'
}],
totalExpenses: 0,
totalIncome: 100
}
},
2019: {
Jan: {
records: [{
id: 789,
date: '01-Jan-2019',
description: 'McD',
amount: 150,
type: 'expense'
}],
totalExpenses: 150,
totalIncome: 0
},
}
}
let year = 2018;
let month = 'Jan';
const yearRecords = records[year] || { [year]: {} };
const monthRecords = yearRecords[month] || { [month]: {} };
const recordList = monthRecords['records'] || [];
const newRec = {id: 666, amount: 9999};
const newRecordList = [...recordList, newRec];
monthRecords['records'] = newRecordList;
monthRecords.totalExpenses = newRecordList.reduce((accumulator, record) => {
return accumulator + record.amount;
}, 0);
console.log({...records, [year]: yearRecords})
I have a list of existing records
, and I'm trying to append new record newRec
into this records
.
The challenge is, key of year might/might not exist, same goes to months. If it existed, append into records
array and increase the totalExpenses
field.
As shown above, I got it working if year/month
existed in records
but if I set it let year = 2020
, it become one level extra in records which is wrong. I've been trying many hours still couldn't figure it out, wondering if there is any easier way to do assertion as above?
Below will be showing wrong result when the year = 2020
let records = {
2018: {
Jan: {
records: [{
id: 123,
date: '01-Jan-2018',
amount: 300,
type: 'expense'
}],
totalExpenses: 300,
totalIncome: 0
},
Feb: {
records: [{
id: 234,
date: '01-Jan-2019',
description: 'Syabas',
amount: 100,
type: 'income'
}],
totalExpenses: 0,
totalIncome: 100
}
},
2019: {
Jan: {
records: [{
id: 789,
date: '01-Jan-2019',
description: 'McD',
amount: 150,
type: 'expense'
}],
totalExpenses: 150,
totalIncome: 0
},
}
}
let year = 2020;
let month = 'Jan';
const yearRecords = records[year] || { [year]: {} };
const monthRecords = yearRecords[month] || { [month]: {} };
const recordList = monthRecords['records'] || [];
const newRec = {id: 666, amount: 9999};
const newRecordList = [...recordList, newRec];
monthRecords['records'] = newRecordList;
monthRecords.totalExpenses = newRecordList.reduce((accumulator, record) => {
return accumulator + record.amount;
}, 0);
console.log({...records, [year]: yearRecords})
You could do this using reduce
method.
let records = {"2018":{"Jan":{"records":[{"id":123,"date":"01-Jan-2018","amount":300,"type":"expense"}],"totalExpenses":300,"totalIncome":0},"Feb":{"records":[{"id":234,"date":"01-Jan-2019","description":"Syabas","amount":100,"type":"income"}],"totalExpenses":0,"totalIncome":100}},"2019":{"Jan":{"records":[{"id":789,"date":"01-Jan-2019","description":"McD","amount":150,"type":"expense"}],"totalExpenses":150,"totalIncome":0}}}
let month = 'Jan';
function update(year, month, obj, target) {
[year, month].reduce(function(r, e, i, a) {
if(!a[i + 1] && r[e]) {
r[e].records.push(obj);
r[e].totalExpenses += obj.amount
}
return r[e] = (r[e] || (a[i + 1] ? {} : {
records: [obj],
totalExpenses: obj.amount,
totalIncome: 0
}))
}, target)
}
update(2018, month, {id: 4, amount: 9999}, records);
update(2020, month, {id: 5, amount: 9999}, records);
console.log(records)