I never get to use ECMA6 in production/work, so I am hoping you all can help me write better code by reviewing my finished sample:
(function() {
'use strict';
class BudgCalc {
constructor(personFullName, yearlyAfterTaxIncome) {
this.name = personFullName;
this.income = this.dollarsToCents(yearlyAfterTaxIncome);
this.initialAfterTaxIncome = this.income;
this.expenses = {
daily: [],
weekly: [],
monthly: [],
yearly: []
}
// To be calculated at runtime
this.incomeBreakdown = {
_startingIncome: this.centsToDollars(this.initialAfterTaxIncome), // _ is so its at the top of the object in the console only not because its private:)
daily: 0,
weekly: 0,
monthly: 0,
yearly: 0
}
// Constants storing occurances per year
this.dateData = {
DAILY: 365,
WEEKLY: 52,
MONTHLY: 12,
YEARLY: 1
}
this.setAmountsAvailableByTimePeriod();
return this;
}
// dollars string to cents int
dollarsToCents(curString) {
var dolCentArr = curString.replace('$', '').replace(',', '').split('.'),
dollarToCent = dolCentArr[0] * 100,
origCents = dolCentArr[1] || 0, // For exact dollar amounts
cents;
if (origCents.length > 2) origCents = [origCents[0], origCents[1]]; // Truncate anything larger than .00
cents = (parseInt(dollarToCent) + parseInt(origCents)); // Avoid type coersion here!
return Math.round(cents);
}
// Turns dollars int to formatted USD currency string
centsToDollars(centsInt) {
var centsStr = `$${(parseInt(centsInt) / 100)}`,
formattedUSMoneyArr = centsStr.split('.'),
centsMember = formattedUSMoneyArr[1] || [],
result;
if (!centsMember.length) return centsStr + '.00'; // Add back in string format when js truncates a whole number (trailing .00's)
else switch (true) {
case centsMember.length === 1:
return centsStr + '0';
break; // .0+0
case centsMember.length === 2:
return centsStr;
break; // Ok format here just return
case centsMember.length > 2:
return formattedUSMoneyArr[0] + '.' + centsMember[0] + centsMember[1];
break; // Truncate larger than 99 cents
}
}
// Sets up the amounts available in time period
setAmountsAvailableByTimePeriod() {
this.incomeBreakdown.daily = this.centsToDollars(this.income / this.dateData.DAILY);
this.incomeBreakdown.weekly = this.centsToDollars(this.income / this.dateData.WEEKLY);
this.incomeBreakdown.monthly = this.centsToDollars(this.income / this.dateData.MONTHLY);
this.incomeBreakdown.yearly = this.centsToDollars(this.income);
return this;
}
setNewExpense(name, recurance, amount) {
var bill = {},
rate = this.dateData[recurance.toUpperCase()],
matchingRecord = this.expenses[recurance];
amount = this.dollarsToCents(amount);
if (this.incomeBreakdown[recurance] && rate && matchingRecord) {
this.income = Math.round(this.income - (amount * rate));
bill[name] = this.centsToDollars(amount);
matchingRecord.push(bill);
this.setAmountsAvailableByTimePeriod();
}
}
getFullReport() {
return {
expenses: this.expenses,
budget: this.incomeBreakdown
}
}
}
class RenderUI extends BudgCalc {
addExpense(nameStr, recuranceStr, amountStr) {
// UI stuff in here, just leaving focus on the logic for now
this.setNewExpense(nameStr, recuranceStr, amountStr);
}
}
var app = new RenderUI('John Doe', (6450 * 24).toString() + '.00');
app.addExpense('health insurance', 'monthly', '$200.00');
app.addExpense('dining', 'daily', '$20.00');
app.addExpense('car payment', 'monthly', '$300.00');
app.addExpense('car insurance payment', 'monthly', '$300.23');
app.addExpense('rent', 'monthly', '$1650.00');
app.addExpense('cable', 'monthly', '175.00');
app.addExpense('food', 'monthly', '$800.00');
app.addExpense('gasoline', 'monthly', '$400.00233');
app.addExpense('electric', 'monthly', '$110.00');
app.addExpense('maggies phone', 'monthly', '$120.00');
app.addExpense('savings', 'monthly', '$820.00');
console.log({
incomeReport: app.getFullReport()
});
})();
Here is a demo: http://codepen.io/nicholasabrams/pen/zqKRYd/