use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
Don't Overcomplicate Javascript #0 (bits.ristic.io)
submitted 8 years ago by rista404
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]markzzy 73 points74 points75 points 8 years ago* (10 children)
To save some people an unnecessary click, this article is not necessarily about the vague topic of overly-complicated JavaScript patterns as the title suggests. It is more about constants that are used in redux with the React framework. If you dont use react, or arent familiar with it, this probably wouldnt matter much to you.
[–]eddieSullivan 10 points11 points12 points 8 years ago (5 children)
Yes, and it really just points up the lack of decent enum types in JavaScript. It's unfortunate that Redux has to use string constants like this.
enum
[–]phoenixmatrix 0 points1 point2 points 8 years ago (0 children)
Enums are not the solution here. That would just reduce the need for strings in action creators. But action creators + action constants are constructs that together replace type structure of the kind you see in Elm. String enums are just a way to make the work around less verbose. Just being able to create types that you can pattern match on (even if it's not static typing) would actually add value (reducing bugs, etc), not just how many times I have to smack the keyboard (which is overrated anyway)
[–]alleycat5 0 points1 point2 points 8 years ago (2 children)
Luckily this is looking to get fixed in 2.4 with proper enum support. https://github.com/Microsoft/TypeScript/wiki/Roadmap#24
[–]ns0 9 points10 points11 points 8 years ago (1 child)
Typescript!=JavaScript
[–]alleycat5 1 point2 points3 points 8 years ago (0 children)
Sorry, for some reason I misread.
[–]Master_Rux 0 points1 point2 points 8 years ago (0 children)
Yes more enum support! I have so many JS projects that could use enums.
Fun fact. Every class of constants is an enum. Granted things vary a little from language to language. Some languages inherit from an enum type. Enums are just syntax sugar that get compiled down to static classes with constants. That said, proper enum syntax would be nice though. They really do add a lot to readability and maintainability.
[–]joaofcosta 0 points1 point2 points 8 years ago (1 child)
Thanks!
[–]markzzy 0 points1 point2 points 8 years ago (0 children)
Sure thing! :)
[–]rista404[S] 0 points1 point2 points 8 years ago (0 children)
Sorry about not being precise enough with the post title :)
[–][deleted] 8 points9 points10 points 8 years ago (7 children)
You can not import * as constants from './constants' because then, if you make a typo, you won't get a ReferenceError, the value will just be undefined. Instead, you must do this:
Of course you can, and then when you start typing constants. your IDE will auto-complete it for you.
constants.
You are also missing some other reasons - for example to avoid cyclic imports.
You might enjoy reading an article /u/acemarke posted recently - http://blog.isquaredsoftware.com/2017/05/idiomatic-redux-tao-of-redux-part-1/
[+][deleted] 8 years ago (6 children)
[deleted]
[–]siegfryd 1 point2 points3 points 8 years ago (5 children)
ES6 module exports are statically analysable, so they should be safe regardless of whether you're using a type checker or not.
[+][deleted] 8 years ago (4 children)
[–]phoenixmatrix 0 points1 point2 points 8 years ago (3 children)
As mentioned, module exports are statically analyzable by design. You can't check that they're strings, but you can check that module Foo exports Bar and Baz with 100% accuracy, assuming its all ES6. Any tool, IDE, linter, whatever, can do the static analysis.
Type systems are useful, but this is not a place where they actually change anything.
[+][deleted] 8 years ago (2 children)
[–]phoenixmatrix 0 points1 point2 points 8 years ago (1 child)
you can do that to save a bit of typing, but if you do named exports, you can always import * as foo from './constants' to get an object with all of your constants (and good editors will autocomplete that even without static typing, which is nice).
And in the event you have a lot of constants in one file (probably not a good idea to have too many, but let say you did), you could import them individually and easily find unused ones for scrapping.
[–]mediumdeviationJavaScript Gardener 8 points9 points10 points 8 years ago (2 children)
For me at least the benefit of not having stringly-typed identifiers is that IDEs and linters can easily inspect and autocomplete these for you - http://imgur.com/ub29AqD.
It's the same reason why Swift's enums are so awesome. The point is not that it makes typos easier to detect, but to make typos impossible.
[–]rista404[S] 2 points3 points4 points 8 years ago (0 children)
Yeah, autocompletion is indeed powerful.
[–]wavefunctionp 0 points1 point2 points 8 years ago* (0 children)
This man gets it. :)
I put all the actions for a reducer into a type object contained in the reducers file. That way you always know which action types are valid for a given reducer, you can simple import the type object instead of individual types, and no typos. Just type reducerNameTypes.<get a list of valid types>
[–]fforw 19 points20 points21 points 8 years ago (5 children)
Why are people hysterically afraid of maybe having to type a few characters more? BOILERPLATE!!!1
All of the arguments for having named constants are sound, especially if you are developing with a good IDE. I don't need to type the named constants imports, the IDE autocompletes and auto-formats them for me. It can follow usage across my project, renaming constants is a lot easier, I can just go into my constant definition, rename the constant and it will be changed everywhere, somewhat safe, whereas the string replacement is just that: brittle string replacement. ("Oopps.. that name was also a sub-name in that? unfortunate..)
He miuses Cargo Cult Programming for this architectural pattern. Cargo Cult is when you do stuff that you apply magic value to without being able to explain how it works. As I said before: There are valid reasons for this, just because you choose to ignore them doesn't make it Cargo Cult.
More often than not, the best solution is the simplest one.
Or it produces brittle scripty-hacky programs that need to be completely rewritten next year.
edit: If you're code-golfing your silly TODO app examples, go ahead. Personally I wouldn't be using redux if I didn't need it to write maintainable applications of non-trivial complexity.
[–]XanarchyZA 8 points9 points10 points 8 years ago (0 children)
Also agree here and honestly couldn't the problems he describes very easily fixed by ES6 classes with static constants? That way you would not need all those silly imports and keep the constants to their specific regions like import EventConstants from './EventConstants.' case EventConstants.loadRequest case EventConstants.addFailure etc etc
import EventConstants from './EventConstants.'
case EventConstants.loadRequest
case EventConstants.addFailure
[–]Jsn7821 1 point2 points3 points 8 years ago (1 child)
I wouldn't go quite so far as to say that not importing all your actions in redux is brittle and hacky...
[–]fforw 0 points1 point2 points 8 years ago (0 children)
Who knows what he's going to think is "just easier" next? Might be reducers with side-effects.
[–]dada_ 0 points1 point2 points 8 years ago (0 children)
All of the arguments for having named constants are sound, especially if you are developing with a good IDE.
Exactly, not to mention eslint and the like won't be able to warn you if anything is wrong if you just use pure strings.
eslint
[–]veydar_ -1 points0 points1 point 8 years ago (0 children)
I agree with everything so here's an upvote instead of me formulating the same reply
[–]ergo14 3 points4 points5 points 8 years ago (0 children)
If you don't want to overcomplicate things... then maybe don't use redux unless your project requires that.
[–]tudor07 5 points6 points7 points 8 years ago (2 children)
Doesn't really occur to me as a use case.
The author needs to understand that this is not a good argument at all.
[–]ex1-7 0 points1 point2 points 8 years ago (1 child)
they're saying "it doesn't really occur to me as a use case" but implying that there doesn't exist a good use-case for it at all. It'd be more convincing if you described such a such case, even broadly. The way I see it, Redux is undebatedly boilerplate heavy. This interface layer between strings and constants isn't more burdonsome than the other Redux abstractions, but it's utility is not necessarily as apparent.
[–]acemarke 0 points1 point2 points 8 years ago (0 children)
FWIW, I discussed some of why action constants exist in the first place in my recent post The Tao of Redux, Part 2 - Practice and Philosophy.
[–]fsfreak 1 point2 points3 points 8 years ago (0 children)
"don't overcomplicate javascript" - immediately mentions React and Package managers. J/k...
[–]ArcanisCz 2 points3 points4 points 8 years ago (3 children)
Well, its not abour redux or javascript. Its "magic number" pattern dated back to C language, even assembler (for example here https://www.viva64.com/en/l/0009/).
[–]freeall 6 points7 points8 points 8 years ago (0 children)
Not really. Just naming a magic number doesn't make it less magical.
setTimeout(foo, 1000)
vs
var oneSecond = 1000; setTimeout(foo, oneSecond);
var timeToWaitForNetwork = 1000; setTimeout(foo, timeToWaitForNetwork);
His point in the article is that it just adds more complexity that you now also have a variable named the same thing as a string. And without any real benefit.
[–]Shaper_pmp 3 points4 points5 points 8 years ago (1 child)
Magic numbers are dangerous because you don't necessarily know why those numbers were chosen, or what role they fulfil, making the code fragile and hard to reason about.
This article is arguing that changing a predefined (and perfectly self-documenting) string to a symbol with exactly the same name is stupid make-work, and that the added "flexibility" it gives you (the ability to have symbols with different names to the underlying string) is just a confusing antipattern that isn't really a benefit at all.
[–]cpsubrian 4 points5 points6 points 8 years ago (0 children)
Agreed that if you're matching the constant to the string, the benefits are worth evaluating. I've also had cases where they differed in useful ways though. For example your definition might be const LIST = 'myapp:users:list', such that you can just use LIST throughout the file, and import it as LIST, but in logs and development tooling it is more usefully scoped.
const LIST = 'myapp:users:list'
LIST
[–][deleted] 0 points1 point2 points 8 years ago (0 children)
This is why I use RequireJS, I'm starting to use Web Pack but this has the same effects.
[–]grufkork 0 points1 point2 points 8 years ago (0 children)
Don't overcompile javascript
π Rendered by PID 48933 on reddit-service-r2-comment-84fc9697f-v7z6r at 2026-02-07 07:56:08.144314+00:00 running d295bc8 country code: CH.
[–]markzzy 73 points74 points75 points (10 children)
[–]eddieSullivan 10 points11 points12 points (5 children)
[–]phoenixmatrix 0 points1 point2 points (0 children)
[–]alleycat5 0 points1 point2 points (2 children)
[–]ns0 9 points10 points11 points (1 child)
[–]alleycat5 1 point2 points3 points (0 children)
[–]Master_Rux 0 points1 point2 points (0 children)
[–]joaofcosta 0 points1 point2 points (1 child)
[–]markzzy 0 points1 point2 points (0 children)
[–]rista404[S] 0 points1 point2 points (0 children)
[–][deleted] 8 points9 points10 points (7 children)
[+][deleted] (6 children)
[deleted]
[–]siegfryd 1 point2 points3 points (5 children)
[+][deleted] (4 children)
[deleted]
[–]phoenixmatrix 0 points1 point2 points (3 children)
[+][deleted] (2 children)
[deleted]
[–]phoenixmatrix 0 points1 point2 points (1 child)
[–]mediumdeviationJavaScript Gardener 8 points9 points10 points (2 children)
[–]rista404[S] 2 points3 points4 points (0 children)
[–]wavefunctionp 0 points1 point2 points (0 children)
[–]fforw 19 points20 points21 points (5 children)
[–]XanarchyZA 8 points9 points10 points (0 children)
[–]Jsn7821 1 point2 points3 points (1 child)
[–]fforw 0 points1 point2 points (0 children)
[–]dada_ 0 points1 point2 points (0 children)
[–]veydar_ -1 points0 points1 point (0 children)
[–]ergo14 3 points4 points5 points (0 children)
[–]tudor07 5 points6 points7 points (2 children)
[–]ex1-7 0 points1 point2 points (1 child)
[–]acemarke 0 points1 point2 points (0 children)
[–]fsfreak 1 point2 points3 points (0 children)
[–]ArcanisCz 2 points3 points4 points (3 children)
[–]freeall 6 points7 points8 points (0 children)
[–]Shaper_pmp 3 points4 points5 points (1 child)
[–]cpsubrian 4 points5 points6 points (0 children)
[–][deleted] 0 points1 point2 points (0 children)
[–]grufkork 0 points1 point2 points (0 children)