11# ` Elm ` (_ ish_ )
22
3- ## (How to Build a Front-end Micro-Framework _ From Scratch_ )
4-
53![ elmlogo-ish] ( https://user-images.githubusercontent.com/194400/43213139-b70a4c68-902d-11e8-8162-3c7cb56b6360.png )
64<!-- the colors are deliberately "a bit off" to emphasize that
75this is a "inspired by" but really a "poor immitation" of Elm! -->
86
97` Elm ` (_ ish_ ) is an ** ` Elm ` ** -_ inspired_ ` JavaScript ` (** ES5** )
10- fully functional front-end _ micro_ -framework.[ <sup >1</sup >] ( #notes )
8+ fully functional front-end _ micro_ -framework from _ scratch _ .[ <sup >1</sup >] ( #notes )
119
12- <br />< br />
10+ <br />
1311
1412## _ Why?_
1513
@@ -22,19 +20,19 @@ into a "micro framework" is to: <br />
2220*** simplify*** the Todo List application code
2321to _ just_
2422[ "** application logic** "] ( https://en.wikipedia.org/wiki/Business_logic ) . <br />
25- ** b)** _ demonstrate _ a *** re-useable*** (_ fully-tested_ )
23+ ** b)** _ demo _ a *** re-useable*** (_ fully-tested_ )
2624"** micro-framework** " that allows us
2725to _ practice_ using The Elm Architecture ("TEA").<br />
2826** c)** promote the ** mindset** of writing ** tests _ first_ **
2927and ** ` then ` ** the _ least_ amount of code necessary to pass the test
3028(_ while meeting the acceptance criteria_ ).
3129
3230> _ ** Test** & ** Document-Driven Development** is ** easy** and it's ** easily**
33- one of the ** best habits** to form in your software development career.
31+ one of the ** best habits** to form in your software development " career" .
3432This walkthrough shows ** how** you can do it ** the right way**
3533from the ** start** of a project._
3634
37- <br />< br />
35+ <br />
3836
3937## _ What?_
4038
@@ -64,7 +62,7 @@ https://github.com/dwyl/learn-elm-architecture-in-javascript/issues <br />
6462@dwyl is a "safe space" and we are all here to help don't be shy/afraid; <br />
6563the _ more_ questions you ask, the more you are helping yourself and _ others_ !
6664
67- <br />< br />
65+ <br />
6866
6967## _ How_ ?
7068
@@ -131,10 +129,8 @@ The `view` function _invokes_ several "helper" functions
131129which create HTML ("DOM") elements e.g: ` <section> ` , ` <div> ` & ` <button> ` ;
132130these _ can_ (_ will_ ) be generalised (_ below_ ).
133131
134-
135132Let's start with a couple of "_ familiar_ " _ generic_ functions
136- (_ which we used in the "counter-reset" example_ ):
137- ` init ` , ` empty ` and ` mount ` . <br />
133+ (_ which we used in the "counter-reset" example_ ): ` empty ` and ` mount ` . <br />
138134
139135<br />
140136
@@ -283,8 +279,6 @@ function empty(node) {
283279
284280#### Add ` module.exports ` statement to "export" the ` empty ` function
285281
286- Remember to add a line in the ` module.exports ` Object at the end of the file:
287-
288282Adding the function to the ` elmish.js ` file is a good _ start_ ,
289283but we need to *** ` export ` *** it to be able to _ invoke_ it in our test. <br />
290284Add the following code at the end of ` examples/todo-list/elmish.js ` :
@@ -310,7 +304,6 @@ Boom! our first test is passing!
310304(_ the test has ** 3 assertions** , that's why Tape says "tests 3. pass 3"_ ).
311305
312306
313-
314307### ` mount ` the App
315308
316309The ` mount ` function is the "glue" or "wiring" function that
@@ -590,7 +583,8 @@ The `JSDOC` comment for our `add_attributes` function is:
590583/**
591584* add_attributes applies the desired attributes to the desired node.
592585* Note: this function is "impure" because it "mutates" the node.
593- * however it is idempotent; the "side effect" is only applied once.
586+ * however it is idempotent; the "side effect" is only applied once
587+ * and no other nodes in the DOM are "affected" (undesirably).
594588* @param {Array.<String>} attrlist list of attributes to be applied to the node
595589* @param {Object} node DOM node upon which attribute(s) should be applied
596590* @example
@@ -617,37 +611,98 @@ test('elmish.add_attributes applies class HTML attribute to a node', function (t
617611});
618612```
619613
620- Given the code in the test above,
621- take a moment to think of how _ you_ would write,
614+ If you (_ attempt to_ ) run this test (_ and you ** should** _ ),
615+ you will see something like this:
616+
617+ ![ image] ( https://user-images.githubusercontent.com/194400/43414770-af5ee0e4-942b-11e8-9d1c-1cbab3adc136.png )
618+
619+ Test is failing because the ` elmish.add_attributes ` function does not _ exist_ .
620+
621+ Go ahead and _ create_ the ` elmish.add_attributes ` function
622+ (_ just the function without passing the test_ ) and _ export_ it in ` elmish.js ` :
623+ ``` js
624+ /**
625+ * add_attributes applies the desired attributes to the desired node.
626+ * Note: this function is "impure" because it "mutates" the node.
627+ * however it is idempotent; the "side effect" is only applied once
628+ * and no other nodes in the DOM are "affected" (undesirably).
629+ * @param {Array.<String>} attrlist list of attributes to be applied to the node
630+ * @param {Object} node DOM node upon which attribute(s) should be applied
631+ * @example
632+ * // returns node with attributes applied
633+ * div = add_attributes ([" class=item" , " id=mydiv" , " active=true" ], div);
634+ */
635+ function add_attributes (attrlist , node ) {
636+ if (attrlist && attrlist .length ) {
637+ attrlist .forEach (function (attr ) { // apply each prop in array
638+ var a = attr .split (' =' );
639+ switch (a[0 ]) {
640+ // code to make test pass goes here ...
641+ default :
642+ break ;
643+ }
644+ });
645+ }
646+ return node;
647+ }
648+ // ... at the end of the file, "export" the add_attributes funciton:
649+ if (typeof module !== ' undefined' && module .exports ) {
650+ module .exports = {
651+ add_attributes: add_attributes, // export the function so we can test it!
652+ empty: empty,
653+ mount: mount
654+ }
655+ }
656+ ```
657+
658+ When you re-run the test you will see something like this:
659+ ![ image] ( https://user-images.githubusercontent.com/194400/43416008-ff63d70e-942e-11e8-97ee-6544efb7d43a.png )
660+ The function _ exists_ but it does not make the tests pass.
661+ Your _ quest_ is to turn this ** ` 0 ` ** into a ** ` 1 ` ** .
662+
663+ Given the ** ` JSDOC ` ** comment and _ test_ above,
664+ take a moment to think of how _ you_ would write
622665the ` add_attributes ` function to apply a CSS ` class ` to an element. <br />
623666Note: we have _ seen_ the code _ before_ in the ` counter ` example.
624667The difference is this time we want it to be "generic";
625668we want to apply a CSS ` class ` to _ any_ DOM node.
626669
627670If you can, make the test _ pass_
628671by writing the ` add_attributes ` function.
629- (_ don't forget to_ ` export ` _ the function at the end of the file_ ).
672+ (_ don't forget to_ ` export ` _ the function at the bottom of the file_ ).
630673
631- If you get "stuck", checkout:
632- https://github.com/dwyl/learn-elm-architecture-in-javascript/tree/master/examples/todo-list/elmish.js < br />
674+ If you get "stuck", checkout the _ complete _ example :
675+ [ /examples/todo-list/elmish.js ] ( https://github.com/dwyl/learn-elm-architecture-in-javascript/tree/master/examples/todo-list/elmish.js )
633676
677+ > ** Note 1** : it's not "cheating" to look at "the solution",
678+ the whole point of having a step-by-step tutorial
679+ is that you can fill-in any "gaps" if you get "stuck",
680+ but you should only check _ after_ making
681+ a good attempt to write the code _ yourself_ .
682+ <br />
634683
635- > ** Note** : The ` add_attributes ` function is "impure" as it "mutates"
684+ > ** Note 2 ** : The ` add_attributes ` function is "impure" as it "mutates"
636685 the target DOM ` node ` , this is more of a "fact of life" in JavaScript,
637686and given that the application of attributes
638687to DOM node(s) is idempotent we aren't "concerned" with "side effects";
639688the attribute will only be applied _ once_ to the node
640689regardless of how many times the ` add_attributes ` function is called.
641690see: https://en.wikipedia.org/wiki/Idempotence
642691
643-
644692For reference, the Elm HTML Attributes function on Elm package is:
645693http://package.elm-lang.org/packages/elm-lang/html/2.0.0/Html-Attributes
646694
695+ Once you make the test _ pass_ you _ should_ see the following in your Terminal:
696+ ![ image] ( https://user-images.githubusercontent.com/194400/43416304-d06339da-942f-11e8-9546-06af9c494a45.png )
697+
698+ <!-- Onto the next one! https://vimeo.com/8503138 -->
699+
700+ <br />
701+
647702#### Input ` placeholder ` Attribute
648703
649704The ` <input> ` form element (_ where we create new Todo List items_ )
650- has a helpful ` placeholder ` _ prompting_ us with a question:
705+ has a helpful ` placeholder ` attribute _ prompting_ us with a question:
651706"_ What needs to be done?_ "
652707
653708Add the following test to the ` test/elmish.test.js ` file: <br />
@@ -666,7 +721,14 @@ test('elmish.add_attributes set placeholder on <input> element', function (t) {
666721});
667722```
668723
669- Write the necessary code to make this test _ pass_ in ` elmish.js ` .
724+
725+
726+
727+ Write the necessary code in the ` add_attributes ` function of ` elmish.js `
728+ to make this test _ pass_ .
729+
730+ If you get "stuck", checkout the _ complete_ example:
731+ [ /examples/todo-list/elmish.js] ( https://github.com/dwyl/learn-elm-architecture-in-javascript/tree/master/examples/todo-list/elmish.js )
670732
671733
672734#### Input ` autofocus `
@@ -771,7 +833,8 @@ test.only('elmish.add_attributes set "for" attribute <label> element', function
771833});
772834```
773835
774- Write the "case" in to make this test _ pass_ in ` elmish.js ` .
836+ Add the "` case ` " in the ` add_attributes ` function's ` switch ` statement
837+ to make this test _ pass_ in ` elmish.js ` .
775838
776839
777840#### ` <input> ` attribute ` type `
@@ -1503,7 +1566,7 @@ We are going to make **3 adjustments** to this code
15031566to use ` setItem ` and ` getItem ` ,
15041567but _ first_ let's write a *** test*** for the desired outcome!
15051568
1506- Add the following _ test code_ to your ` test/elmish.test.js ` file: <br />:
1569+ Add the following _ test code_ to your ` test/elmish.test.js ` file: <br />
15071570
15081571``` js
15091572// Testing localStorage requires a "polyfil" because it's unavailable in JSDOM:
0 commit comments