3 ways to avoid if-else hell in JavaScript
4 minute read | Jul 26, 2024
engineering
Here are three ways to avoid if-else hell in JavaScript.
- Use
Array.includes
for multiple criteria - Return early to avoid nesting
- Separate logic in a dictionary
Imagine we are writing a program to determine the priority of an issue affecting a piece of equipment given the associated impact.
Here is the bad way of using nested if-else statements. The logic quickly becomes unclear and difficult to maintain.
// BAD WAY - Using nested IF ELSE statements to determine priority
let determinePriorityIfElse = (issue) => {
let equipment = issue.equipment
let impact = issue.impact
// Major equipment priority rules
if (equipment === "chiller" || equipment === "boiler" || equipment === "coolingtower") {
if (impact === "safety" || impact === "uptime" || impact === "water") {
return "urgent"
} else if (impact === "energy") {
return "maintenance"
} else {
return "low"
}
}
// Secondary equipment priority rules
if (equipment === "lighting" || equipment === "meter") {
if (impact === "safety") {
return "urgent"
} else if (impact === "uptime" || impact === "water" || impact === "energy") {
return "maintenance"
} else {
return "low"
}
}
}
let issue = {
equipment: "coolingtower",
impact: "energy"
}
determinePriorityIfElse(issue) // 'maintenance'
Use Array.includes
and return early
Use Array.includes
when checking multiple criteria. Capture criteria rules within arrays early in your logic. Return early to reduce nesting.
Advantages to if-else
Improves maintainability, adding new equipment affected and associated impact can be done by updating the equipment and impacts arrays.
// BETTER WAY - Using Array.includes for multiple criteria
let determinePriorityArrayIncludes = (issue) => {
// Major equipment priority rules
const majorEquipment = ["chiller", "boiler", "coolingtower"]
const urgentImpactsMajor = ["safety", "uptime", "water"]
const maintenanceImpactsMajor = ["energy"]
// Secondary equipment priority rules
const secondaryEquipment = ["lighting", "meter"]
const urgentImpactsSecondary = ["safety"]
const maintenanceImpactsSecondary = ["uptime", "water", "energy"]
let equipment = issue.equipment
let impact = issue.impact
// Determine priority for major equipment
if (majorEquipment.includes(equipment)) {
if (urgentImpactsMajor.includes(impact)) return "urgent"
if (maintenanceImpactsMajor.includes(impact)) return "maintenance"
return "low"
}
// Determine priority for secondary equipment
if (secondaryEquipment.includes(equipment)) {
if (urgentImpactsSecondary.includes(impact)) return "urgent"
if (maintenanceImpactsSecondary.includes(impact)) return "maintenance"
return "low"
}
// Default priority if no match found
return "low"
}
let issue = {
equipment: "coolingtower",
impact: "energy"
}
determinePriorityArrayIncludes(issue) // 'maintenance'
Separate logic in a dictionary
Capture priority rules in a separate dictionary object named equipmentImpactPriorityMap
. Add each equipment as an object with every impact as a property with the associated priority.
To determine the issue priority, look up the equipment and associated impact - as expressed by determinePriorityDictionary(issue)
.
Advantages to if-else
Better clarity and scalability. Separating out the logic into a config file makes it easier to debug and allow feedback from non-technical teams. Matches mental model of looking up the equipment and associated impact to find the determined priority.
// BETTER WAY - Separate logic in a dictionary
const equipmentImpactPriorityMap = {
chiller: {
safety: 'urgent',
uptime: 'urgent',
water: 'urgent',
energy: 'maintenance',
other: 'low'
},
boiler: {
safety: 'urgent',
uptime: 'urgent',
water: 'urgent',
energy: 'maintenance',
other: 'low'
},
coolingtower: {
safety: 'urgent',
uptime: 'urgent',
water: 'urgent',
energy: 'maintenance',
other: 'low'
},
lighting: {
safety: 'urgent',
uptime: 'maintenance',
water: 'maintenance',
energy: 'maintenance',
other: 'low'
},
meter: {
safety: 'urgent',
uptime: 'maintenance',
water: 'maintenance',
energy: 'maintenance',
other: 'low'
}
};
let determinePriorityDictionary = (issue) => {
return equipmentImpactPriorityMap[issue.equipment][issue.impact]
}
let issue = {
equipment: "coolingtower",
impact: "energy"
}
determinePriorityDictionary(issue) // 'maintenance'
Want more tips?
Get future posts with actionable tips in under 5 minutes and a bonus cheat sheet on '10 Biases Everyone Should Know'.
Your email stays private. No ads ever. Unsubscribe anytime.