Stop using boolean states
They are more dangerous than you think.

Just a guy who loves to write code and watch anime.
Search for a command to run...
They are more dangerous than you think.

Just a guy who loves to write code and watch anime.
No comments yet. Be the first to comment.
Qualities that make outstanding builders.

Bipedal vs quadrupedal: how many legs This is about the number of legs the creature walks on. Bipedal. Two legs. Humans, ostriches, T-rex, kangaroos, most fantasy humanoids. Quadrupedal. Four legs. Do

Intro You hear "lerp" and "smoothstep" everywhere in game dev. They sound like math jargon. They're not. Both are small tools that do the same job: smoothly move from one value to another. The problem

What is Kinematics Kinematics is the math field. It's the study of how things move without worrying about forces (which would be dynamics). FK and IK are the two branches: forward kinematics and inver

Intro Textures are usually the biggest cost in a 3D scene. Memory, bandwidth, and load time all get eaten by them. Resizing them is the obvious lever. There's more. This post is about the less obvious

We often use boolean states to keep track of whether something is loading.
Usually, it works as expected.
But maybe you should stop doing it. It's almost always better to have a status.
Let's dive into an example to clarify the dangers of using boolean states. I will stick to plain JavaScript for demonstration purposes, but it applies to any frameworks you'd be using.
To make things a bit clear, I'm taking the extreme approach. Let's look at a piece of code for our registration process and examine how boolean states could become problematic:
let isValidating = false;
let isCreatingAccount = false;
let isSendingEmail = false;
let isRegistrationComplete = false;
let hasValidationError = false;
let hasCreationError = false;
let hasEmailError = false;
function registerUser(userData) {
isValidating = true;
// Step 1: Validate user data
validate(userData, (validationResult) => {
isValidating = false;
if (!validationResult.ok) {
hasValidationError = true;
return;
}
// Step 2: Create account
isCreatingAccount = true;
createAccount(userData, (creationResult) => {
isCreatingAccount = false;
if (!creationResult.ok) {
hasCreationError = true;
return;
}
// Step 3: Send welcome email
isSendingEmail = true;
sendWelcomeEmail(userData, (emailResult) => {
isSendingEmail = false;
if (!emailResult.ok) {
hasEmailError = true;
return;
}
// Step 4: Registration complete
isRegistrationComplete = true;
});
});
});
}
How can this become problematic?
Complex conditional logic: At each step, you need to check multiple flags to understand the current state.
Hard to maintain: If a new step or error condition is added to the process, you need to add more flags and update the logic in several places.
Risk of contradictory states: There's a risk that multiple flags could be true at the same time due to bugs, leading to states that don't make sense.
Let's take a look at how this would be different when using a status.
let registrationStatus = 'idle'; // Can be 'idle', 'validating', 'creatingAccount', 'sendingEmail', 'complete', 'error'
function registerUser(userData) {
updateRegistrationStatus('validating');
// Step 1: Validate user data
validate(userData, (validationResult) => {
if (!validationResult.ok) {
updateRegistrationStatus('error', validationResult.error);
return;
}
updateRegistrationStatus('creatingAccount');
// Step 2: Create account
createAccount(userData, (creationResult) => {
if (!creationResult.ok) {
updateRegistrationStatus('error', creationResult.error);
return;
}
updateRegistrationStatus('sendingEmail');
// Step 3: Send welcome email
sendWelcomeEmail(userData, (emailResult) => {
if (!emailResult.ok) {
updateRegistrationStatus('error', emailResult.error);
return;
}
// Step 4: Registration complete
updateRegistrationStatus('complete');
});
});
});
}
function updateRegistrationStatus(newStatus, error) {
registrationStatus = newStatus;
if (error) {
console.error(`Registration error: ${error}`);
}
console.log(`Registration status: ${registrationStatus}`);
}
This is so much easier to maintain, change and use.
We can only be in one state at a time.
You might wonder what could happen if someone mistypes a status?
Then use a typed language!
If that isn't possible, use a constant to be consistent with the naming of the different statuses.
Stick to using statuses, not boolean states.