airbnb / airbnb/javascript

Provide clarity around chained function indents

Open
#1,566 4 comments 2 reactions 0 assignees View on GitHub
editorial pull request wanted
Dominant language
JavaScript
Stars
148k
Forks
26.6k
PR merge metrics
No merged PRs in 30d

Description

My coworkers and I are having trouble deciding how best to indent chained function calls, covered in section [19.6 - Whitespace > Chains](https://github.com/airbnb/javascript/blob/eslint-config-airbnb-v15.1.0/README.md#whitespace--chains)

It appears to me that one of the 'good' examples given doesn't actually pass ESLinting:
```
// good
const leds = stage.selectAll('.led')
.data(data)
.enter().append('svg:svg')
.classed('led', true)
.attr('width', (radius + margin) * 2)
.append('svg:g')
.attr('transform', `translate(${radius + margin},${radius + margin})`)
.call(tron.led);`
```

In particular, it complains about the indentation being 4 spaces instead of 2, for the 5 lines where that's the case.

What's more, even though it might technically be permitted, there is some weirdness in this example that we think should be elaborated upon and/or clarified. Here are two examples:

1. the second line (` .data(data)`) is indented 4 spaces, which at first glance seems pretty weird since it's two gutters in from it's parent. It makes more sense if the first line were split into two, though, e.g.
```
const leds = stage
.selectAll('.led')
.data(data)
.enter().append('svg:svg')
...
```
2. the third line, although also technically allowed (<= two chains per line), also strikes us a kind of code smell since, if using this level of nesting/indenting/detail, why not put each item on it's own line to increase legibility? e.g.
```
...
.enter()
.append('svg:svg')
...
```

Overall, we had some pretty involved discussion around when and where to use which, and often it seemed to be difficult to reason about because the semantics of the indenting seemed to depend on the semantics of the methods being called, which is tough to be consistent about. There are different strategies to deal with this, but it would be nice if this guide had an opinion that we could rely upon, instead of having to debate the merits of each alternative.

---

For instance, in #19, the issue that seems to have introduced function chaining rules, @quirkyjack proposes that
> Blocks at even indent level are all acting on the last selector in the chain, [e.g.]
```
$('#foo')
.find('.baz')
.doSomething()
.end()
.find('.moo')
.doSomethingElse()
```
...whereas in [jQuery's `.end()` docs](https://api.jquery.com/end/)...
> A long jQuery chain can be visualized as a structured code block, with filtering methods providing the openings of nested blocks and end() methods closing them:
```
$( "ul.first" )
.find( ".foo" )
.css( "background-color", "red" )
.end()
.find( ".bar" )
.css( "background-color", "green" )
.end();
```
Surely both should be preferred to a flat-indented equivalent (since the indents do add clarity and readability via grouping), but how should they be enforced consistently? Or even just pass linting, as the case may be. A 'flat-indenting' example:
```
// tough to follow
$( "ul.first" )
.find( ".foo" )
.css( "background-color", "red" )
.end()
.deferrablePlugin()
.then(handler)
.catch(errorHandler)
.closest( ".bar" )
.css( "background-color", "green" )
.parent()
.chainable($el => {
// long function
})
.prevSibling();

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with section 19.6, “Whitespace > Chains,” in README.md and compare its examples with the ESLint behavior described in the issue. Review issue #19 and the linked jQuery .end() documentation for the competing indentation models. Done means the guide states a consistent opinion, clarifies the examples, and shows patterns that pass linting.

Written by the indexing model from the issue text.

Assessment

Tech stack
eslint, javascript
Domain
documentation
Issue type
Documentation
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.