Skip to content

Commit 42e0a4a

Browse files
committed
add instructsion for elmish.init function to elmish.md for #44
1 parent f94ecd9 commit 42e0a4a

File tree

5 files changed

+840
-732
lines changed

5 files changed

+840
-732
lines changed

README.md

+28-9
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,14 @@ of a completely new (_functional_) programming language!
4646
_Organizing_ `code` in a Web (_or Mobile_) Application
4747
is _really easy_ to ***over-complicate***, <br />
4848
_especially_ when you are just starting out and there
49-
are dozens of competing ideas <br />
50-
all claiming to be the "_right way_"...
49+
are _dozens_ of competing ideas
50+
all _claiming_ to be the "***right way***"...
5151

5252
When we encounter this type of "_what is the **right way**_?"
53-
question <br />
54-
we always follow [***Occam's Razor***](https://en.wikipedia.org/wiki/Occam%27s_razor) and _ask_:
53+
question, <br />
54+
we always follow
55+
[***Occam's Razor***](https://en.wikipedia.org/wiki/Occam%27s_razor)
56+
and _ask_:
5557
what is the ***simplest way***? <br />
5658
In the case of web application organization,
5759
the ***answer*** is:
@@ -73,6 +75,14 @@ very easy!
7375
such as
7476
[Model-view-Presenter](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93presenter) or "Model-View-ViewModel" (MVVM) which is "overkill" for most apps_.)
7577

78+
> _**Note**: **don't panic** if any of the terms above are strange
79+
or even confusing to you right now.
80+
> Our **quest** is to put all the concepts into **context**.
81+
> And if you get "**stuck**" at any point, we are here to help!
82+
> Simply **open a question** on GitHub:_
83+
[github.com/dwyl/**learn-elm-architecture**-in-javascript/**issues**](https://github.com/dwyl/learn-elm-architecture-in-javascript/issues)
84+
85+
7686
## _Who? (Should I Read/Learn This...?)_
7787

7888
[![everybodys-gotta-learn-sometime](https://cloud.githubusercontent.com/assets/194400/25806590/a1619644-33fb-11e7-8b84-1a21be188fb7.png)](https://www.youtube.com/results?q=The+Korgis+-+Everybody%27s+Gotta+Learn+Sometime)
@@ -83,7 +93,7 @@ their code/app in a _sane_, predictable and testable way.
8393

8494
### _Prerequisites_?
8595

86-
![all-you-need-is-less](https://cloud.githubusercontent.com/assets/194400/25772135/a4230490-325b-11e7-9f12-da19fa4eb5e9.png)
96+
[![all-you-need-is-less](https://cloud.githubusercontent.com/assets/194400/25772135/a4230490-325b-11e7-9f12-da19fa4eb5e9.png)](https://www.ted.com/talks/graham_hill_less_stuff_more_happiness)
8797

8898
+ **_Basic_ JavaScript Knowledge**.
8999
see: [github.com/dwyl/**Javascript**-the-**Good-Parts**-notes](https://github.com/iteles/Javascript-the-Good-Parts-notes)
@@ -99,16 +109,18 @@ If you have **_any_ questions**, ***please ask***: <br />
99109

100110
## _What?_
101111

102-
![image](https://cloud.githubusercontent.com/assets/194400/25772120/3fa2492c-325b-11e7-9aee-90b059360c14.png)
112+
[![image](https://cloud.githubusercontent.com/assets/194400/25772120/3fa2492c-325b-11e7-9aee-90b059360c14.png)](https://youtu.be/yYCmhHFhopA?t=4s)
103113

104114
### A _Complete Beginner's_ Guide to "MUV"
105115

106116
Start with a few definitions:
107117

108-
+ **Model** - or "data model" is the place where all data stored;
118+
+ **Model** - or "data model" is the place where all data is stored;
109119
often referred to as the application's `state`.
110120
+ **Update** - how the app handles `actions` performed
111-
by people and `update` the `state`.
121+
by people and `update` the `state`,
122+
usually organised as a `switch` with various `case` statements corresponding
123+
to the different "_actions_" the user can take in your App.
112124
+ **View** - what people using the app can _see_;
113125
a way to `view` the Model (counter) as `HTML`
114126
rendered in a web browser.
@@ -135,7 +147,14 @@ Creative Commons License
135147

136148
</div>
137149

138-
If this diagram is not clear (_yet_), again, don't panic,
150+
In the "View Theatre" diagram, the:
151+
+ **`model`** is the ensamble of characters (_or "**puppets**"_)
152+
+ **`update`** is the function that transforms (_"changes"_) the `model`
153+
(_the "**puppeteer**"_).
154+
+ **`view`** what the audience sees through "view port" (_stage_).
155+
156+
157+
> If this diagram is not clear (_yet_), again, don't panic,
139158
it will all be clarified when you start seeing it in _action_ (_below_)!
140159

141160

elmish.md

+122-33
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# `Elm`(_ish_)
22

3-
### How to Build a Front-end Micro-Framework _From Scratch_
3+
### (How to Build a Front-end Micro-Framework _From Scratch_)
44

55
![elmlogo-ish](https://user-images.githubusercontent.com/194400/43213139-b70a4c68-902d-11e8-8162-3c7cb56b6360.png)
66
<!-- the colors are deliberately "a bit off" to emphasize that
@@ -78,26 +78,18 @@ please see:
7878
and
7979
[front-end-with-tape.md](https://github.com/dwyl/learn-tape/blob/master/front-end-with-tape.md)
8080

81-
### Start by Creating the Files
82-
83-
It's "OK" to ask: "_Where do I **start** (my **TDD** quest)?_" <br />
84-
The answer is: create **two** new files:
85-
`examples/todo-list/elmish.js` and `test/elmish.test.js`
86-
87-
We will create a couple of tests and their corresponding functions _next_
88-
but first, let's take a moment to think about what we _can_ generalise
89-
from the code we wrote for our "counter" example at the start of this tutorial.
9081

9182
### What _Can_ We _Generalise_ ?
9283

93-
Our **first step** in creating `Elm`(_ish_) is to consider
94-
what _can_ be _generalised_ into
84+
Our **first step** in creating `Elm`(_ish_)
85+
is to _re-visit_ the functions we wrote for the "counter app"
86+
and consider what _can_ be _generalised_ into
9587
an application-independent re-useable framework.
9688

9789
> Our **rule-of-thumb** is: anything that creates (_or destroys_)
9890
a DOM element or looks like "plumbing"
99-
(_e.g: "routing" or "managing state"_) is _generic_
100-
and should thus be abstracted into the `Elm`(_ish_) framework.
91+
(_that which is common to **all apps**, e.g: "routing" or "managing state"_)
92+
is _generic_ and should thus be abstracted into the `Elm`(_ish_) framework.
10193

10294

10395
Recall that there are **3 parts** to the Elm Architecture:
@@ -134,21 +126,106 @@ these _can_ (_will_) be generalised (_below_).
134126

135127

136128
Let's start with a couple of "_familiar_" _generic_ functions
137-
(_which we saw and used in the "counter" example_):
138-
`empty` and `mount`. <br />
129+
(_which we used in the "counter-reset" example_):
130+
`init`, `empty` and `mount`. <br />
139131

140132
<br />
141133

142-
#### `empty` the DOM
134+
### Start by Creating the Files
135+
136+
It's _essential_ to ask: "_Where do I **start** (my **TDD** quest)?_" <br />
137+
The answer is: create **two** new files:
138+
`examples/todo-list/elmish.js` and `test/elmish.test.js`
139+
140+
141+
### Test Setup
142+
143+
In order to run our test, we need some "setup" code
144+
that "requires" the libraries so we can _execute_ the functions.
145+
146+
In the `test/elmish.test.js` file, type the following code:
147+
```js
148+
const test = require('tape'); // https://github.com/dwyl/learn-tape
149+
const fs = require('fs'); // to read html files (see below)
150+
const path = require('path'); // so we can open files cross-platform
151+
const html = fs.readFileSync(path.resolve(__dirname,
152+
'../examples/todo-list/index.html')); // sample HTML file to initialise JSDOM.
153+
require('jsdom-global')(html); // https://github.com/rstacruz/jsdom-global
154+
const elmish = require('../examples/todo-list/elmish.js'); // functions to test
155+
elmish.init(document); // pass JSDOM into elmish for DOM functions
156+
const id = 'test-app'; // all tests use 'test-app' as root element
157+
```
158+
159+
> Most of this code should be _familiar_ to you
160+
if you have followed previous tutorials.
161+
> If anything is _unclear_ please revisit
162+
https://github.com/dwyl/learn-tape
163+
and
164+
165+
If you attempt to run this code using the command:
166+
```sh
167+
node test/elmish.test.js
168+
```
169+
170+
you will see something like the following:
171+
![no-init-function](https://user-images.githubusercontent.com/194400/43359605-b8cc9418-929c-11e8-92d6-97feb8c67596.png)
172+
173+
This is because we do not have anything in the `elmish.js`, yet.
174+
Let's address that now!
175+
176+
177+
### Add `init` function
178+
179+
Open the `examples/todo-list/elmish.js` file and add the following code:
180+
181+
```js
182+
183+
184+
/**
185+
* `init` initialises the document (Global) variable for DOM operations.
186+
* @param {Object} doc window.document in browser and JSDOM.document in tests.
187+
* @return {Object} document returns whatever is passed in.
188+
*/
189+
function init(doc){
190+
document = doc; // this is used for instantiating JSDOM for testing.
191+
return document;
192+
}
193+
```
194+
195+
This code is simply to allow us to "initialise" `Elm`(_ish_)
196+
with a "fake" DOM (`JSDOM`) so that we can _test_ it.
197+
198+
199+
### Add `module.exports` to "export" the `init` function
200+
201+
Adding the function to the `elmish.js` file is a good _start_,
202+
but we need to ***`export`*** it to be able to _invoke_ it in our test.
203+
Let's add the following code at the end of `examples/todo-list/elmish.js`:
204+
205+
```js
206+
/* module.exports is needed to run the functions using Node.js for testing! */
207+
/* istanbul ignore next */
208+
if (typeof module !== 'undefined' && module.exports) {
209+
module.exports = {
210+
init: init
211+
}
212+
} else { init(document);
213+
```
214+
215+
216+
217+
218+
### `empty` the DOM
143219
144220
Start by _describing_ what the `empty` function _does_. <br />
145221
This is both to clarify our _own_ understanding
146222
as the people _writing_ the code <br />
147223
and to _clearly communicate_ with the **`humans` _reading_** the code.
148224
149-
##### Function Description
225+
#### `empty` Function _Description_
150226
151-
The `empty` function clears the DOM elements out of a specific "root" element.
227+
The `empty` function deletes all DOM elements
228+
from within a specific "root" element.
152229
We use it to erase the DOM before re-rendering our app.
153230
154231
Following "**_Document(ation)_ Driven Development**",
@@ -158,12 +235,13 @@ with _just_ the function description:
158235
159236
```js
160237
/**
161-
* `empty` clears the DOM elements out of a specific "root" element.
238+
* `empty` deletes all the DOM elements from within a specific "root" element.
162239
* it is used to erase the DOM before re-rendering the app.
163240
*/
164241
```
165242
Writing out the function documentation _first_
166-
helps us _think_ about the functionality.
243+
allows (_our subconscious_) time to _think_ about the functionality
244+
and how to _test_ for the "_acceptance criteria_".
167245
Even if you know _exactly_ what code needs to be written,
168246
_resist_ the temptation to write the code until it is documented.
169247
Even if you are writing code alone,
@@ -172,12 +250,15 @@ who does _not_ (_already_) "know the solution"
172250
and you are _explaining_ it to them.
173251
174252
253+
#### `empty` Function _Test_
175254
176-
Given that we _know_ we are going to use the `empty`
177-
178-
function we used previously in our `counter`,
255+
We previously used the `empty` function in our `counter`,
179256
`counter-reset` and `multiple-counters` examples (_in the "basic" TEA tutorial_)
180-
we can write a _test_ for the `empty` function quite easily.
257+
so we have a "head start" on writing the test.
258+
259+
> _The **reason**(s) we write the **test first**
260+
even when we (already) know the "solution" is:_ <br />
261+
>
181262
182263
183264
In the `test/elmish.test.js` file, type the following code:
@@ -187,7 +268,7 @@ const fs = require('fs'); // to read html files (see below)
187268
const path = require('path'); // so we can open files cross-platform
188269
const elmish = require('../examples/todo-list/elmish.js'); // functions to test
189270
const html = fs.readFileSync(path.resolve(__dirname,
190-
'../examples/todo-list/index.html')); // sample HTML file for JSDOM to load
271+
'../examples/todo-list/index.html')); // sample HTML file to initialise JSDOM.
191272
require('jsdom-global')(html); // https://github.com/rstacruz/jsdom-global
192273
elmish.init(document); // pass JSDOM into elmish for DOM functions
193274
const id = 'test-app'; // all tests use 'test-app' as root element
@@ -223,17 +304,19 @@ issue***!](https://github.com/dwyl/learn-elm-architecture-in-javascript/issues)
223304
_It's **essential** that you **understand** each **character**
224305
in the code **before** continuing to **avoid** "**confusion**" later._
225306
307+
#### `empty` Function _Implementation_
308+
226309
Now that we have the **test** for our `empty` function written,
227310
we can add the `empty` function to `examples/todo-list/elmish.js`:
228311
```js
229312
/**
230-
* `empty` the contents of a given DOM element "node" (before re-rendering).
313+
* `empty` deletes all the DOM elements from within a specific "root" element.
314+
* it is used to erase the DOM before re-rendering the app.
231315
* This is the *fastest* way according to: stackoverflow.com/a/3955238/1148249
232-
* @param {Object} node the exact DOM node you want to empty
316+
* @param {Object} node the exact ("parent") DOM node you want to empty
233317
* @example
234318
* // returns true (once the 'app' node is emptied)
235-
* const node = document.getElementById('app');
236-
* empty(node);
319+
* empty(document.getElementById('app'));
237320
*/
238321
function empty(node) {
239322
while (node.lastChild) {
@@ -242,12 +325,18 @@ function empty(node) {
242325
}
243326
```
244327
245-
If the **comment syntax**
246-
above the function definition
247-
is _unfamiliar_,
328+
If the **comment syntax** above the function definition is _unfamiliar_,
248329
please see:
249330
[https://github.com/dwyl/**learn-jsdoc**](https://github.com/dwyl/learn-jsdoc)
250331
332+
When you run the test in your terminal with the command
333+
`node test/elmish.test.js`
334+
you should see something _similar_ to this:
335+
336+
337+
338+
339+
251340
252341
### `mount` the App
253342

0 commit comments

Comments
 (0)