DEV Community

Cover image for State Management: How to tell a bad boolean from a good boolean

State Management: How to tell a bad boolean from a good boolean

Matt Pocock on May 27, 2021

TL;DR: Bad booleans represent state. Good booleans are derived from state. When you're managing state in your app, it's easy to fall prey to bad b...
Collapse
 
ultrox profile image
Marko Vujanic • Edited

You are missing, idle or 'not-asked' state here.

Recently I got interested into Elm and what I really like about that community is that they promote data structure first approach for building apps.

For curious, have a look more in depth about ideas borrowed from Elm here
lillo.dev/articles/slaying-a-ui-an...

Collapse
 
mattpocockuk profile image
Matt Pocock

I'm assuming the data fetch is made when you first enter the page, meaning that the 'idle' state will likely only show for one render - so is not worth handling.

Love the look of elm but never tried it!

Collapse
 
lucas_castro profile image
Lucas Castro

Also, a common pattern that makes "idle" unnecessary on auto-loading states, is to start with the status as "loading" by default/definition.

Collapse
 
ahyagoub40 profile image
Ahmed Yagoub

Interesting article. Would love to see how the enum is defined and used in JavaScript too : )

Collapse
 
mdledoux profile image
Martin Ledoux

Ahmed,
This looks like a good and simple approach to achieving Enum in JS:

tutorialspoint.com/what-is-the-syn...

Note

Be sure to use Object.freeze(), as objects (and Arrays) can still have their properties/elements modified, even when declared as const.

Observation

Even in the author's post using TypeScript, Matt technically did not use an Enum construct, but rather he simulated Enum by defining a new Type. Enum is actually supported in TypeScript: typescriptlang.org/docs/handbook/e...

I'm not sure why he did this instead of defining an actual Enum, but it certainly seems to achieve the same end result. With that said, it sounds like you probably do not use TypeScript, so this observation is probably not very relevant for you.

Collapse
 
mattpocockuk profile image
Matt Pocock

Hello! I find having strings defined like this makes for a better TS experience and easier debugging. It also makes the article easier to read for non-TS users.

Thread Thread
 
randomuser profile image
polyrytm • Edited

I get what you are saying, and i always opt for the way you did it here, but they are not enums. The approach is the same, but I don't really see why you would want to name them incorrectly. If readers want to find out more and search for 'typescript enums' they will see different things than you show here.

You are using a union of string literals.
typescriptlang.org/docs/handbook/2...

Thread Thread
 
mattpocockuk profile image
Matt Pocock • Edited

Even though I haven't used the Typescript 'enum' constructor, what I've shown above is an enumerated set of values - an enum. I've used the above syntax because it's more common to declare enumerated events/messages/actions using union types than TS enums.

Thread Thread
 
randomuser profile image
polyrytm

Saying you're using a feature in typescript called enums will have interested people searching for 'typescript enums'. They will end up on a long 'typescript enums' page in the TS manual which is about 'typescript enums'... and none of it is about what you use here.

But more confusement is better i guess :)

Thread Thread
 
mattpocockuk profile image
Matt Pocock

For those reading this thread, TS enums can achieve exactly the same behaviour as I described above.

Collapse
 
ahyagoub40 profile image
Ahmed Yagoub

Yeah, I don’t use TS and haven’t learned yet. Thanks for this

Collapse
 
mattpocockuk profile image
Matt Pocock

Added as an addendum :)

Collapse
 
mongopark profile image
Ola' John Ajiboye

While this is good, it's not possible in Vanilla JS where you can't use enums or types. A simple idiomatic way to do this is to append .finally{isLoading = false} to the async block.

Collapse
 
mattpocockuk profile image
Matt Pocock

Added as an addendum.

The code you describe will still result in the bug described in the article. The most sensible way to do this (resulting in the most predictable program with the fewest LOC) is with an enum.

Collapse
 
damms005 profile image
Damilola Emmanuel Olowookere

"Good boolean" practise is clearly the way to go. But curiously, is setting isLoading=false in .finally() not guarantee that there can't be a loading and complete state at the same time, which is what the described bug is about?

Thread Thread
 
mattpocockuk profile image
Matt Pocock

Sure, you can of course fix the bug by adding more lines of code. But why choose an approach which forces you write defensive code to prevent impossible states?

Thread Thread
 
damms005 profile image
Damilola Emmanuel Olowookere

It seems you do not get my point. The case you made with good booleans, as I said, is the way to go. I am not arguing that. I am only trying to understand the statement you made with The code you describe will still result in the bug described in the article. Assuming good boolean is not to be used for whatever reason, according to that statement, setting isLoading=false in .finally() will still cause bug. I do not think so

Thread Thread
 
mattpocockuk profile image
Matt Pocock

No - your approach would cause a different bug - you'd need to set isComplete to false at the start to fully ensure that the states were not mutual. As well as doing a similar thing for the errors. I think we both agree on the main point of the article.

Collapse
 
omril321 profile image
Omri Lavi

Thanks for the post! It reminded me of the talk Crafting Stateful Styles with State Machines by David Khourshid

Collapse
 
mrdulin profile image
official_dulin • Edited

I used to use pending, fulfilled and rejected

Collapse
 
mahamoti1129 profile image
Mahamoti1129

Just so you know, there's a reddit user reposting this article as his own.

reddit.com/r/softwaredevelopment/c...

Collapse
 
mattpocockuk profile image
Matt Pocock

Thanks for the heads up

Collapse
 
unfor19 profile image
Meir Gabay

Great article, thanks for the info, I'll definitely try to adopt this concept

Collapse
 
waugh profile image
waugh

Before publishing, go on a "which" hunt. If there isn't a comma in front of "which", substitute "that". Unless you meant what comma followed by "which" means, in which case, put that.

Collapse
 
diogocorrea profile image
Diogo Corrêa

Nice post! I aways used booleans the "bad way". Gonna remember to make them derive from state next time ;)

Collapse
 
mrjjwright profile image
John Wright • Edited

Great article! This is what I also learned from Michel Westrate from Mobx, who teaches : "minimal state, derive, derive, derive!".

Collapse
 
guivern profile image
Guillermo Verón

It makes perfect sense and even has made me think that representing the same (state) with different variables is not a good abstraction.
Great article! Thanks for sharing it.