A place to cache linked articles (think custom and personal wayback machine)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.html 27KB

4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang=fr>
  4. <!-- Has to be within the first 1024 bytes, hence before the <title>
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset=utf-8>
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name=viewport content="width=device-width,minimum-scale=1,initial-scale=1,shrink-to-fit=no">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>Why junior developers are learning bad habits from Angular (archive) — David Larlet</title>
  13. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  14. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons/apple-touch-icon.png">
  15. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons/favicon-32x32.png">
  16. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons/favicon-16x16.png">
  17. <link rel="manifest" href="/manifest.json">
  18. <link rel="mask-icon" href="/static/david/icons/safari-pinned-tab.svg" color="#5bbad5">
  19. <link rel="shortcut icon" href="/static/david/icons/favicon.ico">
  20. <meta name="apple-mobile-web-app-title" content="David Larlet">
  21. <meta name="application-name" content="David Larlet">
  22. <meta name="msapplication-TileColor" content="#da532c">
  23. <meta name="msapplication-config" content="/static/david/icons/browserconfig.xml">
  24. <meta name="theme-color" content="#f0f0ea">
  25. <!-- That good ol' feed, subscribe :p. -->
  26. <link rel=alternate type="application/atom+xml" title=Feed href="/david/log/">
  27. <meta name="robots" content="noindex, nofollow">
  28. <meta content="origin-when-cross-origin" name="referrer">
  29. <!-- Canonical URL for SEO purposes -->
  30. <link rel="canonical" href="https://javascriptkicks.com/stories/3718">
  31. <style>
  32. /* http://meyerweb.com/eric/tools/css/reset/ */
  33. html, body, div, span,
  34. h1, h2, h3, h4, h5, h6, p, blockquote, pre,
  35. a, abbr, address, big, cite, code,
  36. del, dfn, em, img, ins,
  37. small, strike, strong, tt, var,
  38. dl, dt, dd, ol, ul, li,
  39. fieldset, form, label, legend,
  40. table, caption, tbody, tfoot, thead, tr, th, td,
  41. article, aside, canvas, details, embed,
  42. figure, figcaption, footer, header, hgroup,
  43. menu, nav, output, ruby, section, summary,
  44. time, mark, audio, video {
  45. margin: 0;
  46. padding: 0;
  47. border: 0;
  48. font-size: 100%;
  49. font: inherit;
  50. vertical-align: baseline;
  51. }
  52. /* HTML5 display-role reset for older browsers */
  53. article, aside, details, figcaption, figure,
  54. footer, header, hgroup, menu, nav, section { display: block; }
  55. body { line-height: 1; }
  56. blockquote, q { quotes: none; }
  57. blockquote:before, blockquote:after,
  58. q:before, q:after {
  59. content: '';
  60. content: none;
  61. }
  62. table {
  63. border-collapse: collapse;
  64. border-spacing: 0;
  65. }
  66. /* http://practicaltypography.com/equity.html */
  67. /* https://calendar.perfplanet.com/2016/no-font-face-bulletproof-syntax/ */
  68. /* https://www.filamentgroup.com/lab/js-web-fonts.html */
  69. @font-face {
  70. font-family: 'EquityTextB';
  71. src: url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff2') format('woff2'),
  72. url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff') format('woff');
  73. font-weight: 300;
  74. font-style: normal;
  75. font-display: swap;
  76. }
  77. @font-face {
  78. font-family: 'EquityTextB';
  79. src: url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff2') format('woff2'),
  80. url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff') format('woff');
  81. font-weight: 300;
  82. font-style: italic;
  83. font-display: swap;
  84. }
  85. @font-face {
  86. font-family: 'EquityTextB';
  87. src: url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff2') format('woff2'),
  88. url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff') format('woff');
  89. font-weight: 700;
  90. font-style: normal;
  91. font-display: swap;
  92. }
  93. @font-face {
  94. font-family: 'ConcourseT3';
  95. src: url('/static/david/css/fonts/concourse_t3_regular-webfont-20190806.woff2') format('woff2'),
  96. url('/static/david/css/fonts/concourse_t3_regular-webfont-20190806.woff') format('woff');
  97. font-weight: 300;
  98. font-style: normal;
  99. font-display: swap;
  100. }
  101. /* http://practice.typekit.com/lesson/caring-about-opentype-features/ */
  102. body {
  103. /* http://www.cssfontstack.com/ Palatino 99% Win 86% Mac */
  104. font-family: "EquityTextB", Palatino, serif;
  105. background-color: #f0f0ea;
  106. color: #07486c;
  107. font-kerning: normal;
  108. -moz-osx-font-smoothing: grayscale;
  109. -webkit-font-smoothing: subpixel-antialiased;
  110. text-rendering: optimizeLegibility;
  111. font-variant-ligatures: common-ligatures contextual;
  112. font-feature-settings: "kern", "liga", "clig", "calt";
  113. }
  114. pre, code, kbd, samp, var, tt {
  115. font-family: 'TriplicateT4c', monospace;
  116. }
  117. em {
  118. font-style: italic;
  119. color: #323a45;
  120. }
  121. strong {
  122. font-weight: bold;
  123. color: black;
  124. }
  125. nav {
  126. background-color: #323a45;
  127. color: #f0f0ea;
  128. display: flex;
  129. justify-content: space-around;
  130. padding: 1rem .5rem;
  131. }
  132. nav:last-child {
  133. border-bottom: 1vh solid #2d7474;
  134. }
  135. nav a {
  136. color: #f0f0ea;
  137. }
  138. nav abbr {
  139. border-bottom: 1px dotted white;
  140. }
  141. h1 {
  142. border-top: 1vh solid #2d7474;
  143. border-bottom: .2vh dotted #2d7474;
  144. background-color: #e3e1e1;
  145. color: #323a45;
  146. text-align: center;
  147. padding: 5rem 0 4rem 0;
  148. width: 100%;
  149. font-family: 'ConcourseT3';
  150. display: flex;
  151. flex-direction: column;
  152. }
  153. h1.single {
  154. padding-bottom: 10rem;
  155. }
  156. h1 span {
  157. position: absolute;
  158. top: 1vh;
  159. left: 20%;
  160. line-height: 0;
  161. }
  162. h1 span a {
  163. line-height: 1.7;
  164. padding: 1rem 1.2rem .6rem 1.2rem;
  165. border-radius: 0 0 6% 6%;
  166. background: #2d7474;
  167. font-size: 1.3rem;
  168. color: white;
  169. text-decoration: none;
  170. }
  171. h2 {
  172. margin: 4rem 0 1rem;
  173. border-top: .2vh solid #2d7474;
  174. padding-top: 1vh;
  175. }
  176. h3 {
  177. text-align: center;
  178. margin: 3rem 0 .75em;
  179. }
  180. hr {
  181. height: .4rem;
  182. width: .4rem;
  183. border-radius: .4rem;
  184. background: #07486c;
  185. margin: 2.5rem auto;
  186. }
  187. time {
  188. display: bloc;
  189. margin-left: 0 !important;
  190. }
  191. ul, ol {
  192. margin: 2rem;
  193. }
  194. ul {
  195. list-style-type: square;
  196. }
  197. a {
  198. text-decoration-skip-ink: auto;
  199. text-decoration-thickness: 0.05em;
  200. text-underline-offset: 0.09em;
  201. }
  202. article {
  203. max-width: 50rem;
  204. display: flex;
  205. flex-direction: column;
  206. margin: 2rem auto;
  207. }
  208. article.single {
  209. border-top: .2vh dotted #2d7474;
  210. margin: -6rem auto 1rem auto;
  211. background: #f0f0ea;
  212. padding: 2rem;
  213. }
  214. article p:last-child {
  215. margin-bottom: 1rem;
  216. }
  217. p {
  218. padding: 0 .5rem;
  219. margin-left: 3rem;
  220. }
  221. p + p,
  222. figure + p {
  223. margin-top: 2rem;
  224. }
  225. blockquote {
  226. background-color: #e3e1e1;
  227. border-left: .5vw solid #2d7474;
  228. display: flex;
  229. flex-direction: column;
  230. align-items: center;
  231. padding: 1rem;
  232. margin: 1.5rem;
  233. }
  234. blockquote cite {
  235. font-style: italic;
  236. }
  237. blockquote p {
  238. margin-left: 0;
  239. }
  240. figure {
  241. border-top: .2vh solid #2d7474;
  242. background-color: #e3e1e1;
  243. text-align: center;
  244. padding: 1.5rem 0;
  245. margin: 1rem 0 0;
  246. font-size: 1.5rem;
  247. width: 100%;
  248. }
  249. figure img {
  250. max-width: 250px;
  251. max-height: 250px;
  252. border: .5vw solid #323a45;
  253. padding: 1px;
  254. }
  255. figcaption {
  256. padding: 1rem;
  257. line-height: 1.4;
  258. }
  259. aside {
  260. display: flex;
  261. flex-direction: column;
  262. background-color: #e3e1e1;
  263. padding: 1rem 0;
  264. border-bottom: .2vh solid #07486c;
  265. }
  266. aside p {
  267. max-width: 50rem;
  268. margin: 0 auto;
  269. }
  270. /* https://fvsch.com/code/css-locks/ */
  271. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  272. font-size: 1rem;
  273. line-height: calc( 1.5em + 0.2 * 1rem );
  274. }
  275. h1 {
  276. font-size: 1.9rem;
  277. line-height: calc( 1.2em + 0.2 * 1rem );
  278. }
  279. h2 {
  280. font-size: 1.6rem;
  281. line-height: calc( 1.3em + 0.2 * 1rem );
  282. }
  283. h3 {
  284. font-size: 1.35rem;
  285. line-height: calc( 1.4em + 0.2 * 1rem );
  286. }
  287. @media (min-width: 20em) {
  288. /* The (100vw - 20rem) / (50 - 20) part
  289. resolves to 0-1rem, depending on the
  290. viewport width (between 20em and 50em). */
  291. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  292. font-size: calc( 1rem + .6 * (100vw - 20rem) / (50 - 20) );
  293. line-height: calc( 1.5em + 0.2 * (100vw - 50rem) / (20 - 50) );
  294. margin-left: 0;
  295. }
  296. h1 {
  297. font-size: calc( 1.9rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  298. line-height: calc( 1.2em + 0.2 * (100vw - 50rem) / (20 - 50) );
  299. }
  300. h2 {
  301. font-size: calc( 1.5rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  302. line-height: calc( 1.3em + 0.2 * (100vw - 50rem) / (20 - 50) );
  303. }
  304. h3 {
  305. font-size: calc( 1.35rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  306. line-height: calc( 1.4em + 0.2 * (100vw - 50rem) / (20 - 50) );
  307. }
  308. }
  309. @media (min-width: 50em) {
  310. /* The right part of the addition *must* be a
  311. rem value. In this example we *could* change
  312. the whole declaration to font-size:2.5rem,
  313. but if our baseline value was not expressed
  314. in rem we would have to use calc. */
  315. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  316. font-size: calc( 1rem + .6 * 1rem );
  317. line-height: 1.5em;
  318. }
  319. p, li, pre, details {
  320. margin-left: 3rem;
  321. }
  322. h1 {
  323. font-size: calc( 1.9rem + 1.5 * 1rem );
  324. line-height: 1.2em;
  325. }
  326. h2 {
  327. font-size: calc( 1.5rem + 1.5 * 1rem );
  328. line-height: 1.3em;
  329. }
  330. h3 {
  331. font-size: calc( 1.35rem + 1.5 * 1rem );
  332. line-height: 1.4em;
  333. }
  334. figure img {
  335. max-width: 500px;
  336. max-height: 500px;
  337. }
  338. }
  339. figure.unsquared {
  340. margin-bottom: 1.5rem;
  341. }
  342. figure.unsquared img {
  343. height: inherit;
  344. }
  345. @media print {
  346. body { font-size: 100%; }
  347. a:after { content: " (" attr(href) ")"; }
  348. a, a:link, a:visited, a:after {
  349. text-decoration: underline;
  350. text-shadow: none !important;
  351. background-image: none !important;
  352. background: white;
  353. color: black;
  354. }
  355. abbr[title] { border-bottom: 0; }
  356. abbr[title]:after { content: " (" attr(title) ")"; }
  357. img { page-break-inside: avoid; }
  358. @page { margin: 2cm .5cm; }
  359. h1, h2, h3 { page-break-after: avoid; }
  360. p3 { orphans: 3; widows: 3; }
  361. img {
  362. max-width: 250px !important;
  363. max-height: 250px !important;
  364. }
  365. nav, aside { display: none; }
  366. }
  367. ul.with_columns {
  368. column-count: 1;
  369. }
  370. @media (min-width: 20em) {
  371. ul.with_columns {
  372. column-count: 2;
  373. }
  374. }
  375. @media (min-width: 50em) {
  376. ul.with_columns {
  377. column-count: 3;
  378. }
  379. }
  380. ul.with_two_columns {
  381. column-count: 1;
  382. }
  383. @media (min-width: 20em) {
  384. ul.with_two_columns {
  385. column-count: 1;
  386. }
  387. }
  388. @media (min-width: 50em) {
  389. ul.with_two_columns {
  390. column-count: 2;
  391. }
  392. }
  393. .gallery {
  394. display: flex;
  395. flex-wrap: wrap;
  396. justify-content: space-around;
  397. }
  398. .gallery figure img {
  399. margin-left: 1rem;
  400. margin-right: 1rem;
  401. }
  402. .gallery figure figcaption {
  403. font-family: 'ConcourseT3'
  404. }
  405. footer {
  406. font-family: 'ConcourseT3';
  407. display: flex;
  408. flex-direction: column;
  409. border-top: 3px solid white;
  410. padding: 4rem 0;
  411. background-color: #07486c;
  412. color: white;
  413. }
  414. footer > * {
  415. max-width: 50rem;
  416. margin: 0 auto;
  417. }
  418. footer a {
  419. color: #f1c40f;
  420. }
  421. footer .avatar {
  422. width: 200px;
  423. height: 200px;
  424. border-radius: 50%;
  425. float: left;
  426. -webkit-shape-outside: circle();
  427. shape-outside: circle();
  428. margin-right: 2rem;
  429. padding: 2px 5px 5px 2px;
  430. background: white;
  431. border-left: 1px solid #f1c40f;
  432. border-top: 1px solid #f1c40f;
  433. border-right: 5px solid #f1c40f;
  434. border-bottom: 5px solid #f1c40f;
  435. }
  436. </style>
  437. <h1>
  438. <span><a id="jumper" href="#jumpto" title="Un peu perdu ?">?</a></span>
  439. Why junior developers are learning bad habits from Angular (archive)
  440. <time>Pour la pérennité des contenus liés. Non-indexé, retrait sur simple email.</time>
  441. </h1>
  442. <section>
  443. <article>
  444. <h3><a href="https://javascriptkicks.com/stories/3718">Source originale du contenu</a></h3>
  445. <p>TLDR;</p>
  446. <ul>
  447. <li>This is for folks who want some examples backing up my statements from my last post</li>
  448. <li>Basically, juniors fall into patterns of behavior early on, and it's hard to shake them out of it</li>
  449. <li>Angular <strong>requires</strong> some workarounds depending on what you're optimizing for which can quickly become anti-patterns in the hands of junior developers</li>
  450. </ul>
  451. <p>When I wrote the other day about the fact that <a href="https://javascriptkicks.com/stories/2657">I won't be using Angular in my next project</a>, one of the key points I raised was that junior developers are learning some bad habits when working with Angular. Quite a few people agreed with me - primarily because they had experienced it themselves, and that was the end of the discussion.</p>
  452. <p>But on the other hand there were two more camps I noticed; the first being developers who may not have worked on Angular and genuinely want to know why I made those statements, and the second camp, <a href="https://news.ycombinator.com/item?id=8953366">those that said</a> I was just spouting <a href="http://en.wikipedia.org/wiki/Fear,_uncertainty_and_doubt">FUD</a> because I didn't explain myself in detail, which surprised me a bit because those are developers who presumably have been working on Angular and in my opinion should already know about the pitfalls and their effect on juniors. And if they don't already know, then I thought I had linked to enough other (much better) articles explaining those pitfalls.</p>
  453. <p>So either the second camp is somehow blinded and does not want to see, or they're just lazy and didn't bother reading through the linked posts. Given the links, I wasn't particularly worried about explaining myself to the nth degree, plus the fact that my article was already edging up to 2.5K words and would probably lose even more readers if it was any longer. Either way, they're probably not the ones reading here now...</p>
  454. <blockquote>
  455. <p>This post is for those who genuinely want to know, but haven't pieced it together for themselves yet.</p>
  456. </blockquote>
  457. <h2>OK, so why single out junior developers</h2>
  458. <p>Well, firstly, it's because they're obviously the most likely to fall into the traps - but secondly, and most importantly, they don't know right from wrong yet. It's like telling a child not to cross the road without holding an adult's hand. They don't know about cars early on, and hopefully they'll never find out first hand just how destructive they can be. I would like to protect my junior developers in a similar fashion, and Angular isn't helping, but I'll explain why.</p>
  459. <blockquote>
  460. <p>&quot;Traps?!&quot; I hear you say...</p>
  461. </blockquote>
  462. <p>I specifically mentioned &quot;bad habits&quot;, and I chose the term carefully, because habits are typically things you tend to learn early on in a practice, and once they're bedded in, it takes extra-ordinary effort to shake off. Senior developers in my experience tend to have been burned through this cycle once or twice already, and so are more likely to be open to better solutions when they see things just aren't right. Juniors... not so much - they just power on through hoping for a safety net.</p>
  463. <p>For my first example, I'll use <code>$scope</code> as ~~my whipping boy~~ a way to establish a precedent for the differences between senior and junior developers. Consider the following fictitious Angular Controller;</p>
  464. <pre><code class="language-javascript">(function () {
  465. var app = angular.module('jsk', []);
  466. function JskController($scope) {
  467. $scope.anonymous = function () {
  468. var user = !!$scope.username; //Noooooooo!!!
  469. return !user || $scope.username.length === 0;
  470. };
  471. $scope.displayName = function () {
  472. if ($scope.anonymous()) {
  473. return;
  474. }
  475. return $scope.name;
  476. };
  477. }
  478. app.controller('jskCtrl', JskController);
  479. })();
  480. </code></pre>
  481. <p>The <code>Controller</code> is just a wrapper for <code>$scope</code>....why? What's the point in even having it if it's just a proxy? It's <em>supposed</em> to represent the view-model at the very least. This is also typical of developers who do not approach a problem with testing in mind, and have no issue passing <code>$scope</code> around thereby coupling the <code>Controller</code> to the data-binding, and forcing a ton of unnecessary mocking if they even bother to write unit tests in the first place.</p>
  482. <p>Many would not even see the problem here, and just as children don't know cars can hurt, juniors don't know just how destructive this anti-pattern can be to performance, separation of concerns and long term code base maintenance.</p>
  483. <blockquote>
  484. <p><em>This simple little anti-pattern will now pepper your code throughout if not rooted out</em></p>
  485. </blockquote>
  486. <p>And now that the junior developer has done this once, they will do what every junior developer does exceedingly well - they will Copy+Paste their way into oblivion. This simple little anti-pattern will now pepper your code throughout if not rooted out, and <em>that</em> requires an experienced head that knows enough to spot it and provide a better way. Rinse and repeat.</p>
  487. <h2>Polluting other frameworks</h2>
  488. <p>Now take that same junior developer and move them onto another project that just happens to be written with another framework, let's pick <a href="http://durandaljs.com/">Durandal</a> for example. There's significantly more JavaScript™ and a heck of a lot less framework stuff that you touch daily. The same can be said for frameworks like <a href="http://backbonejs.org/">Backbone</a> and <a href="http://ampersandjs.com/">Ampersand</a>. You're basically working with pure code mostly, and using the framework around the periphery where it stays out the way, but where it can be a useful time-saver.</p>
  489. <p>In the hands of a junior fresh out of the Angular project, all of a sudden you see application state get pulled in and passed around <em>just</em> like it was done with Angular. When confronted, they just shrug and say &quot;that's how I did it on that other project&quot; - and so starts the cycle of corrective instruction. The juniors who have never touched Angular, so far in my experience don't tend to exhibit these tendencies straight off the bat. They tend to learn from patterns being used in the code base they're working on and from the most recent, and it took me a long while to see it.</p>
  490. <h2>Other habits juniors learn from Angular</h2>
  491. <p>I'm not going to give an example for each - that was the point of my ~~whipping boy~~ example above. Suffice it to say that this post is long enough already, and that there most certainly is an example you'll be able to find if you Google for it.</p>
  492. <p>Off the top of my head, the list of things juniors do includes, but is not limited to:</p>
  493. <ul>
  494. <li>Overuse of the eventing system (<code>$watch</code>, <code>$emit</code>, <code>$broadcast</code>) leading to performance problems and memory leaks and not realizing it or being able to debug it</li>
  495. <li>Writing <code>Controllers</code> and <code>Directives</code> that take dependencies which make them nearly impossible to test.</li>
  496. <li>Views that are heavily dosed with logic - but more on that later</li>
  497. <li>Their first experience of DI is quite often that in Angular and it's horribly broken. Since the &quot;patch&quot; which fixed the minification issues, it's still really just a square peg in a round hole with woeful support for scope and lifetime and features which most DI gives you for free such as child containers. They end up hating DI and shy away from it on other projects.</li>
  498. <li>Strange bugs that (when called over) have us all scratching our heads until one of use realizes - oh yeah, sorry we forgot to mention that pretty much everything passed around is global, and <code>Directives</code> etc. aren't namespaced, so I see what's happened - you've got a naming collision there</li>
  499. <li>It's getting late, but I hope you get the idea...</li>
  500. </ul>
  501. <h2>Hacks and other debauchery</h2>
  502. <p>Data-binding is broken. Some changes to Angular under the covers have made it in because of this, but having to go back and be explicit about which things should be one-way versus two-way is a big job, especially on large invested code bases with very few tests.</p>
  503. <p>What's that got to do with juniors? Well, they possibly did a lot of the data-binding work up front, and will continue to do so as the app is maintained. Can you trust them to use their judgment as to which type of binding to leverage? Do you even know yourself? Are you sure?</p>
  504. <p>I already explained why I dislike the view templating system, but I mostly dislike it because of what juniors do with it. Apart from being horribly inefficient with the DOM, terribly difficult to read or give out to design agencies, when you leave the juniors alone with them long enough, you'll find that they are exceptionally good at shoving <em>all sorts</em> of logic and programming in there. Maybe not something that would cross the mind of a senior developer straight away, but when you see it, you literally catch yourself saying... &quot;wait...What?!&quot;</p>
  505. <p>You have to go through every commit with a fine toothcomb and rap them on the knuckles each time they do it. But there are so many ways in which they can make this mistake, (because they find all their damn examples on the bloody internet in blog posts like this one) which means that <em>they</em> end up with very red knuckles and <em>I</em> have all my hair torn out. That's the point where I start asking if it is worth it or not. And the answer is no, no it most certainly is not.</p>
  506. <h2>Conclusion</h2>
  507. <p>I know that a lot of the things I've mentioned above can be attributed to a simple fact that juniors make mistakes, and require guidance to get better, but I've been in this game for over 20 years now, and at no point in my career - apart from possibly working with SharePoint ;-) - have I struggled as much to get the juniors to &quot;step away from the keyboard&quot; and <em>think</em> about the crap they're writing.</p>
  508. <p>I hope that this post has gone some way towards helping you understand why I personally want to keep junior developers away from Angular. I hope it hasn't come across as pure <a href="http://en.wikipedia.org/wiki/Fear,_uncertainty_and_doubt">FUD</a>, and rather measured opinion, but by all means, I'm happy to stand corrected if you feel there is a better way, so feel free to leave your comments and we can have a discussion about it!</p>
  509. <p>Until next time,
  510. <a href="https://twitter.com/robertthegrey">RobertTheGrey</a></p>
  511. </article>
  512. </section>
  513. <nav id="jumpto">
  514. <p>
  515. <a href="/david/blog/">Accueil du blog</a> |
  516. <a href="https://javascriptkicks.com/stories/3718">Source originale</a> |
  517. <a href="/david/stream/2019/">Accueil du flux</a>
  518. </p>
  519. </nav>
  520. <footer>
  521. <div>
  522. <img src="/static/david/david-larlet-avatar.jpg" loading="lazy" class="avatar" width="200" height="200">
  523. <p>
  524. Bonjour/Hi!
  525. Je suis <a href="/david/" title="Profil public">David&nbsp;Larlet</a>, je vis actuellement à Montréal et j’alimente cet espace depuis 15 ans. <br>
  526. Si tu as apprécié cette lecture, n’hésite pas à poursuivre ton exploration. Par exemple via les <a href="/david/blog/" title="Expériences bienveillantes">réflexions bimestrielles</a>, la <a href="/david/stream/2019/" title="Pensées (dés)articulées">veille hebdomadaire</a> ou en t’abonnant au <a href="/david/log/" title="S’abonner aux publications via RSS">flux RSS</a> (<a href="/david/blog/2019/flux-rss/" title="Tiens c’est quoi un flux RSS ?">so 2005</a>).
  527. </p>
  528. <p>
  529. Je m’intéresse à la place que je peux avoir dans ce monde. En tant qu’humain, en tant que membre d’une famille et en tant qu’associé d’une coopérative. De temps en temps, je fais aussi des <a href="https://github.com/davidbgk" title="Principalement sur Github mais aussi ailleurs">trucs techniques</a>. Et encore plus rarement, <a href="/david/talks/" title="En ce moment je laisse plutôt la place aux autres">j’en parle</a>.
  530. </p>
  531. <p>
  532. Voici quelques articles choisis :
  533. <a href="/david/blog/2019/faire-equipe/" title="Accéder à l’article complet">Faire équipe</a>,
  534. <a href="/david/blog/2018/bivouac-automnal/" title="Accéder à l’article complet">Bivouac automnal</a>,
  535. <a href="/david/blog/2018/commodite-effondrement/" title="Accéder à l’article complet">Commodité et effondrement</a>,
  536. <a href="/david/blog/2017/donnees-communs/" title="Accéder à l’article complet">Des données aux communs</a>,
  537. <a href="/david/blog/2016/accompagner-enfant/" title="Accéder à l’article complet">Accompagner un enfant</a>,
  538. <a href="/david/blog/2016/senior-developer/" title="Accéder à l’article complet">Senior developer</a>,
  539. <a href="/david/blog/2016/illusion-sociale/" title="Accéder à l’article complet">L’illusion sociale</a>,
  540. <a href="/david/blog/2016/instantane-scopyleft/" title="Accéder à l’article complet">Instantané Scopyleft</a>,
  541. <a href="/david/blog/2016/enseigner-web/" title="Accéder à l’article complet">Enseigner le Web</a>,
  542. <a href="/david/blog/2016/simplicite-defaut/" title="Accéder à l’article complet">Simplicité par défaut</a>,
  543. <a href="/david/blog/2016/minimalisme-esthetique/" title="Accéder à l’article complet">Minimalisme et esthétique</a>,
  544. <a href="/david/blog/2014/un-web-omni-present/" title="Accéder à l’article complet">Un web omni-présent</a>,
  545. <a href="/david/blog/2014/manifeste-developpeur/" title="Accéder à l’article complet">Manifeste de développeur</a>,
  546. <a href="/david/blog/2013/confort-convivialite/" title="Accéder à l’article complet">Confort et convivialité</a>,
  547. <a href="/david/blog/2013/testament-numerique/" title="Accéder à l’article complet">Testament numérique</a>,
  548. et <a href="/david/blog/" title="Accéder aux archives">bien d’autres…</a>
  549. </p>
  550. <p>
  551. On peut <a href="mailto:david%40larlet.fr" title="Envoyer un courriel">échanger par courriel</a>. Si éventuellement tu souhaites que l’on travaille ensemble, tu devrais commencer par consulter le <a href="http://larlet.com">profil dédié à mon activité professionnelle</a> et/ou contacter directement <a href="http://scopyleft.fr/">scopyleft</a>, la <abbr title="Société coopérative et participative">SCOP</abbr> dont je fais partie depuis six ans. Je recommande au préalable de lire <a href="/david/blog/2018/cout-site/" title="Attention ce qui va suivre peut vous choquer">combien coûte un site</a> et pourquoi je suis plutôt favorable à une <a href="/david/pro/devis/" title="Discutons-en !">non-demande de devis</a>.
  552. </p>
  553. <p>
  554. Je ne traque pas ta navigation mais mon
  555. <abbr title="Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33.184162340">hébergeur</abbr>
  556. conserve des logs d’accès.
  557. </p>
  558. </div>
  559. </footer>
  560. <script type="text/javascript">
  561. ;(_ => {
  562. const jumper = document.getElementById('jumper')
  563. jumper.addEventListener('click', e => {
  564. e.preventDefault()
  565. const anchor = e.target.getAttribute('href')
  566. const targetEl = document.getElementById(anchor.substring(1))
  567. targetEl.scrollIntoView({behavior: 'smooth'})
  568. })
  569. })()
  570. </script>