I have written a Node.js application that manages banks and customers. I would like to know the best practices for optimizing my code to make it cleaner and easier to read. Specifically, I am looking for advice on:
Generating dynamic IDs for each new bank.
Improving the overall structure and readability of the code.
Below is the relevant code:
index.js
const Controller = require("./controllers/controller");
// your code start here..
const [command, ...input] = process.argv.slice(2)
switch (command) {
case 'list':
Controller.list()
break;
case 'addBank':
const [name, type] = input
Controller.addBank(name, type)
break;
case 'deleteBank':
const [idBank] = input
Controller.deleteBank(+idBank)
break;
case 'addCustomer':
const [idBank2, name2, ktp, depositAmount] = input
Controller.addCustomer(+idBank2, name2, ktp, depositAmount)
break
case 'deleteCustomer':
const [id, ktpCust] = input
Controller.deleteCustomer(+id, ktpCust)
break
case 'detail':
const [id2] = input
Controller.detail(+id2)
break
case 'addInterest':
Controller.addInterest()
default:
break;
}
View.js
class View {
// parameter tambahkan sesuai kebutuhan
static printError(error) {
console.log(error)
}
static read(data) {
console.log(data)
}
static successAddBank(data) {
console.log(`Bank ${data.name} added succesfully`)
}
static successDelBank(data) {
console.log(`Bank ${data.name} deleted succesfully`)
}
static successAddCust(data) {
console.log(`Customer ${data.name} added succesfully`)
}
static successDelCust(data) {
console.log(`Customer ${data.name} deleted succesfully`)
}
static list(data) {
data = data.map(perCust => {
return {
name: perCust.name,
ktp: perCust.ktp,
depositAmount: Math.floor(perCust.depositAmount)
}
})
console.table(data)
}
}
module.exports = View
class.js
// code here for class release 0
class Bank {
constructor(id, name, type, limit, customers = []) {
this.id = id
this.name = name
this.type = type
this.limit = limit
this.customers = customers
}
}
class LocalBank extends Bank {
constructor(id, name, customers) {
super(id, name, 'LocalBank', 3, customers)
}
}
class NationalBank extends Bank {
constructor(id, name, customers) {
super(id, name, 'NationalBank', 5, customers)
}
}
class Customer {
#ktp
#depositAmount
constructor(name, ktp, depositAmount) {
this.name = name
this.#ktp = ktp
this.#depositAmount = depositAmount
}
get ktp() {
return this.#ktp
}
set ktp(value) {
this.#ktp = value
}
get depositAmount() {
return this.#depositAmount
}
set depositAmount(value) {
this.#depositAmount = value
}
toJSON() {
return {
name: this.name,
ktp: this.#ktp,
depositAmount: this.#depositAmount
}
}
addInterest() {
this.#depositAmount = 1.1 * this.#depositAmount
}
}
class Factory {
static createBank(id, name, type, customers) {
if (type === 'LocalBank') {
return new LocalBank(id, name, customers)
} else if (type === 'NationalBank') {
return new NationalBank(id, name, customers)
}
}
static createCustomer(name, ktp, depositAmount) {
return new Customer(name, ktp, depositAmount)
}
static bulkCust(data) {
return data.map(perCust => {
const { name, ktp, depositAmount } = perCust
return Factory.createCustomer(name, ktp, depositAmount)
})
}
static bulkBank(data) {
return data.map(perBank => {
let { id, name, type, customers } = perBank
customers = Factory.bulkCust(customers)
return Factory.createBank(id, name, type, customers)
})
}
}
module.exports = Factory
model.js
const Factory = require('./class')
const fs = require('fs').promises
class Model {
// parameter tambahkan sesuai kebutuhan
static async saveJSON(data) {
return await fs.writeFile('./data.json', JSON.stringify(data, null, 4), 'utf-8')
}
static async readBank() {
try {
let data = await fs.readFile('./data.json', 'utf-8')
let dataParse = JSON.parse(data)
let instance = Factory.bulkBank(dataParse)
// let instance = dataParse.map(perBank => {
// let { id, name, type, customers } = perBank
// return Factory.createBank(id, name, type, customers)
// })
// instance = instance.map(el => {
// el.customers = el.customers.map(perCust => {
// const { name, ktp, depositAmount } = perCust
// return Factory.createCustomer(name, ktp, depositAmount)
// })
// return el
// })
return instance
} catch (error) {
throw error
}
}
static async createBank(name, type) {
try {
// ambil semua data
// tentukan id yang digunakan
// create instance data baru
// push ke data lama
// save data ke json
let allBank = await this.readBank()
let id = 1
if (allBank.length > 0) {
id = allBank[allBank.length - 1].id + 1
}
// let id2 = allBank.length === 0 ? 1 : allBank[allBank.length - 1].id + 1
let newBank = Factory.createBank(id, name, type)
allBank.push(newBank)
await this.saveJSON(allBank)
// console.log(allBank)
return newBank
} catch (error) {
throw error
}
}
static async deleteBankById(id) {
try {
// ambil semua data
// cari atau find data yang akan dihapus
// filter data yang tdk akan dihapus
// simpan data yang difilter tadi
// kembalikan data yang dihapus
let allBank = await this.readBank()
let delBank = allBank.find(el => el.id === id)
if (!delBank) throw `bank with id ${id} cannot be found`
let filterBank = allBank.filter(el => el.id !== id)
await this.saveJSON(filterBank)
return delBank
} catch (error) {
throw error
}
}
static async createCustomer(idBank, name, ktp, depositAmount) {
try {
let allBank = await this.readBank()
let findBank = allBank.find(el => el.id === idBank)
if (!findBank) throw `bank with id ${idBank} cannot be found`
if (findBank.limit === findBank.customers.length) throw `you cant add more customers`
let newCust = Factory.createCustomer(name, ktp, depositAmount)
findBank.customers.push(newCust)
await this.saveJSON(allBank)
return newCust
} catch (error) {
throw error
}
}
static async deleteCustomerByKtp(id, ktp) {
try {
let allBank = await this.readBank()
let findBank = allBank.find(el => el.id === id)
if (!findBank) throw `bank with id ${id} cannot be found`
let delCust = findBank.customers.find(el => el.ktp === ktp)
if (!delCust) throw `customer with ktp ${ktp} cannot be found`
let filterCust = findBank.customers.filter(el => el.ktp !== ktp)
findBank.customers = filterCust
await this.saveJSON(allBank)
return delCust
} catch (error) {
throw error
}
}
static async readCustomerByBankId(id) {
try {
let allBank = await this.readBank()
let findBank = allBank.find(el => el.id === id)
if (!findBank) throw `bank with id ${id} cannot be found`
return findBank.customers
} catch (error) {
throw error
}
}
static async showCustomer() {
try {
let data = []
let allBank = await this.readBank()
allBank.map(el => {
el.customers.map(perCust => {
perCust.addInterest()
data.push(perCust)
return perCust
})
return el
})
this.saveJSON(allBank)
return data
} catch (error) {
throw error
}
}
}
module.exports = Model
Controller.js
const Model = require('../models/model')
const View = require('../views/view')
class Controller {
// parameter tambahkan sesuai kebutuhan
static async list() {
try {
let data = await Model.readBank()
View.read(data)
} catch (error) {
View.printError(error)
}
}
static async addBank(name, type) {
try {
let data = await Model.createBank(name, type)
View.successAddBank(data)
} catch (error) {
View.printError(error)
}
}
static async deleteBank(id) {
try {
let data = await Model.deleteBankById(id)
View.successDelBank(data)
} catch (error) {
View.printError(error)
}
}
static async addCustomer(id, name, ktp, depositAmount) {
try {
let data = await Model.createCustomer(id, name, ktp, depositAmount)
View.successAddBank(data)
} catch (error) {
View.printError(error)
}
}
static async deleteCustomer(id, ktp) {
try {
let data = await Model.deleteCustomerByKtp(id, ktp)
View.successDelCust(data)
} catch (error) {
View.printError(error)
}
}
static async detail(id) {
try {
let data = await Model.readCustomerByBankId(id)
View.list(data)
} catch (error) {
View.printError(error)
}
}
static async addInterest() {
try {
let data = await Model.showCustomer()
View.list(data)
} catch (error) {
View.printError(error)
}
}
}
module.exports = Controller
New contributor
Kathy Indera is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.