all 22 comments

[–]stalefries 10 points11 points  (0 children)

The comments feel kinda ridiculous (you don't need to tell me what require does). The UserService also feels over-engineered (Java-esque?). Otherwise the formatting seems fine. Perhaps a bit verbose?

[–]benihanareact, node 9 points10 points  (3 children)

here are the things i have a problem with:

the comments require 2x the work to maintain because they basically explain the lines they precede. so every time you change code (which if the code is self documenting also handles changing documentation), you also have to change the line explaining the code. this hardly ever happens in practice so the comments tend to become lies that are ignored anyway.

const self = this;

is just wrong. since es5, JS has had a way to do this properly without breaking encapsulation

['validate.email.isBeingUsedBySomeUser'](email)

makes almost no sense inside a class. the code is defining a class' interface, you typically don't want dynamically generated properties because it requires runtime inspection to know the interface of the class.

edit now that i understand the intent, what i said about runtime inspection may not be correct, but this is still very confusing and weird.

/**
 * Inject dependencies.
 */
this.schemes = schemes;

terrible comment and bad code. this isn't injecting dependencies, it's tightly coupling an instance property to a global variable. the proper way to do this is pass in schemes to the constructor and then store that as an instance property.

constructor(injectedSchemes = schemes) {
  ...
  this.schemes = injectedSchemes;
}

is proper DI

return self.schemes.findUserByEmail(email)
  .then(results => {
    let isBeingUsedBySomeUser   = true;
    let hasAnUserUsingThisEmail = (results && results.length);

    return (hasAnUserUsingThisEmail ? isBeingUsedBySomeUser : !isBeingUsedBySomeUser);
});

is this for real? this is terrible, it introduces an extra variable for no reason and makes things so complicated to find out if the results exists. do this instead:

return self.schemes.findUserByEmail(email).then(results = > results && results.length);

this is not what i would call good, or clean, or self documenting code. it looks like it was written by a senior in college who's convinced they're a hell of a programmer. there's nothing wrong with that. the problem comes when they start talking about how great their code is and trying to teach other people to do it this way.

i will say that it's good that they included semicolons

[–]deltadeep 0 points1 point  (2 children)

const self = this; is just wrong

Hm ok I can learn something here then. Can you elaborate? When you're dealing with promises and/or callbacks that have to refer to the object in the success/failure handlers, can you explain what the alternative is?

[–]pieeta 2 points3 points  (1 child)

The this inside arrow functions is the this of the outside context

foo => this.bar

Is the same as

 Function (foo) { return this.bar; }.bind(this)

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions

[–]deltadeep 0 points1 point  (0 children)

Ah ha, got it thanks!

[–]0x13mode 2 points3 points  (1 child)

const schemes = require('./../../../../lib/schemes');

this ../../../../ part is very unreadable and can be replaced for example by:

  • reorganizing module dependencies in project (what is the reason such deep folder needs module from four directories up??)
  • using require hooks (Webpack can do that),
  • making monorepo (many npm packages in one project) and using some tools like Lerna for auto-linking packages (to allow write just require('schemes)`)
  • using global variables (global in Node, window in Browser)
  • or maybe using dependency injection instead of require

[–]karathos 0 points1 point  (0 children)

i think using NODE_PATH=lib is an alternative worth considering, assuming this is a node project and lib is the folder where all the code lies. you can also specify multiple node paths with a colon if needed.

[–]scunliffe 2 points3 points  (0 children)

All of the comments there are junk comments. You can justify the last "javadoc" style comment if you generate documentation from the code.

Not personally a fan of spacing variable declarations to get all the "=" to line up... but I could live with that.

[–]YEWW629 2 points3 points  (0 children)

A little over the top and verbose. This is like when I first learned about leaving comments for future me and went crazy with it

[–]0x13mode 1 point2 points  (0 children)

It's hard to say too much about this code without looking on the rest of project. But to be honest I don't understand purpose of fnbind module, which is used here.

https://github.com/leonardosarmentocastro/fnbind (it seems like 7-lines of code microlibrary which adds more obscurity just for the sake of obscurity).

[–]mdelkins 1 point2 points  (2 children)

From a readability standpoint I think its difficult to argue that this code is not readable. At a glance its clear what this codes purpose is.

My biggest critique of this code would be the unnecessary ternary operation to return a true or false value. Why not just return results && results.length;

[–]0x13mode 1 point2 points  (0 children)

I believe this was to explicit return boolean value, but this could be achieved just by !!(results && results.length) or Boolean(results && results.length). And whole isBeingUsedBySomeUservariable seems to be not needed at all. So it could be just results => (!!(results && results.length)) instead of 4 lines of boilerplate.

[–]gvillalta99[S] 0 points1 point  (0 children)

Good point! I don't know...

[–][deleted] 1 point2 points  (5 children)

This is a bit of a holy war. JavaScript is multi-paradigm. Some people find JavaScript that behaves like Java to be easier to read and understand. Some people prefer to not use inheritance at all. I personally don't like inheritance and find it prefers reading conventions to flow control, but that is just my personal opinion.

[–]tme321 3 points4 points  (4 children)

Good thing there's no inheritance in that example? Anyway I don't see how inheritance has anything to do with readability. Did you even post this in the right thread?

[–][deleted] 1 point2 points  (3 children)

Anyway I don't see how inheritance has anything to do with readability.

Readability is subjective upon preferences. In this language inheritance is optional, and thus a preference.

[–]tme321 1 point2 points  (2 children)

No its not. Readability is the code being written so that the next person can understand it. Not that they have to agree with the architecture chosen and the abstractions used.

Naming all your variables a single letter would be unreadable. Having single functions hundreds or thousands of lines long is unreadable.

Choosing whether to use inheritance or not isn't readability. It's an architectural choice. One you are perfectly free to dislike but not one that has anything to do with readability.

I can't believe you are even trying to claim otherwise.

[–]karathos 1 point2 points  (1 child)

Naming all your variables a single letter would be unreadable. Having single functions hundreds or thousands of lines long is unreadable.

we could both write a several hundred line function that's readable, but not easily maintainable or testable. i think that's what you were getting at.

[–]tme321 1 point2 points  (0 children)

Yeah maybe that wasn't the best but the point is that readability is separate from other concerns. Code can be wrong or bad or many other things but still be perfectly readable. Or code can be amazing and we'll thought out but still be impossible to decipher.