diff --git a/README.md b/README.md index a4f2a87..51e62d3 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Perhaps: `reactive programming`, `functional programming` and `immutable data` going to **completely change everything**? And, if so, what would that look like in a language that embraces those paradigms? -3. You're taking a [Functional Design and Programming course at San Diego State University](http://www.eli.sdsu.edu/courses/fall15/cs696/index.html) +3. You're taking a [Functional Design and Programming course](http://www.eli.sdsu.edu/courses/fall15/cs696/index.html) at San Diego State University and you have a re-frame/reagent assignment due. You've left the reading a bit late, right? I remember those days. 4. re-frame is impressively buzzword compliant: it has reactivity, unidirectional data flow, pristinely pure functions, @@ -88,7 +88,7 @@ Computationally, each iteration of the loop involves a six domino cascade. One domino triggers the next, which triggers the next, et cetera, until we are -back at the beginning of the loop, whereupoon the dominoes all spring to attention +back at the beginning of the loop, whereupon the dominoes all spring to attention again, ready for the next iteration of the same cascade. Here are the six dominoes ... @@ -118,12 +118,12 @@ change, but sometimes the outside world must also be effected ### 3rd Domino - Effect Handling -The descriptions of `effects` are realised (actioned). This is where the mutation happens. +The descriptions of `effects` are realised (actioned). This is where mutations happens. Now, to a functional programmer, `effects` are scary in a [xenomorph kind of way](https://www.google.com.au/search?q=xenomorph). Nothing messes with functional purity -quite like the need for side effects. But, on the other hand, `effects` are equally +quite like the need for side effects. On the other hand, `effects` are marvelous because they move the app forward. Without them, an app stays stuck in one state forever, never achieving anything. @@ -140,7 +140,7 @@ would an in-memory, central database for the app (more details later). When domino 3 changes this `app state`, it triggers the next part of the cascade involving dominoes 4-5-6. -### There's a formula for it +### There's a formula The 4-5-6 domino cascade implements the formula made famous by Facebook's ground-breaking React library: `v = f(s)` @@ -209,7 +209,7 @@ The loop itself is very mechanical in operation. So, there's a regularity, simplicity and certainty to how a re-frame app goes about its business, which leads, in turn, to an ease in reasoning and debugging. This is -key to why re-frame is so pleasing to work with - it is just so +key to why re-frame is pleasing to work with - it is just so straightforward. ## Managing mutation @@ -218,7 +218,7 @@ The two sub-cascades 1-2-3 and 4-5-6 have a similar structure. In each, it is the second to last domino which computes "descriptions" of mutations required, and it is -the last domino which does the dirty work and realises these descriptions. +the last domino which does the dirty work and realises these descriptions. In both cases, you don't need to worry yourself about this dirty work. re-frame looks after those dominoes. @@ -255,12 +255,12 @@ it has 2 elements: `[:delete-item 2486]`. The first element, ### Code For Domino 2 The `event handler`, `h`, associated with -`:delete-item` is called to compute the `effect` of this event. +`:delete-item`, is called to compute the `effect` of this event. -This handler function, `h`, must take two arguments: the state-of-the-world -and the event, and it must return an effects map. Without going into any -explanations at this early point, here's a sketch of what a handler -might look like: +This handler function, `h`, takes two arguments: a `coeffects` map +which holds the current state of the world (including app state), +and the `event`. It must return a map of `effects` - a description +of how the world should change. Here's a sketch (we are at 30,000 feet): ```clj (defn h [{:keys [db]} event] ;; args: db from coeffect, event @@ -268,11 +268,18 @@ might look like: {:db (dissoc-in db [:items item-id])})) ;; effect is change db ``` +There are mechanisms in re-frame (beyond us here) whereby you can place +all necessary aspects of the world into that first `coeffects` argument, on a +per event-kind basis (different events need to know different things +in order to get their job done). The current application state, `db`, +is one aspect of the world which is invariably needed. + On program startup, `h` would have been associated with `:delete-item` `events` like this: ```clj (re-frame.core/reg-event-fx :delete-item h) ``` +Which says "when you see a `:delete-item` event, use `h` to handle it". ### Code For Domino 3 @@ -280,13 +287,13 @@ An `effect handler` (function) actions the `effects` returned by `h`: ```clj {:db (dissoc-in db [:items item-id])} ``` -So that's a map. The keys identify the required kind of `effect`, and the values -supply further details. +So that's a map. The keys identify the required kinds of `effect`, and the values +supply further details. This map only has one key, so there's only one effect. -A key of `:db` means to update the app state, with the new computed value. +A key of `:db` means to update the app state with the key's value. This update of "app state" is a mutative step, facilitated by re-frame -when it sees a `:db` effect. +which has a built in effects handler for the `:db` effect. Why the name `:db`? re-frame sees "app state" as something of an in-memory database. @@ -311,6 +318,7 @@ On program startup, such a query-fn must be associated with an id, ```clj (re-frame.core/reg-sub :query-items query-fn) ``` +Which says "when you see a query (subscribe) for `:query-items`, use `query-fn` to handle it". ### Code For Domino 5 @@ -329,8 +337,7 @@ for the deleted item, obviously, but otherwise the same DOM as last time). ``` Notice how `items` is "sourced" from "app state" via `subscribe`. It is called with a query id -to identify what data it needs - in Domino 4 we associated the query id `:query-items` with -the function for that computation). +to identify what data it needs. ### Code For Domino 6 @@ -471,13 +478,13 @@ represent a point in the possible design space, with pros and cons. And, yes, re-frame is fast, straight out of the box. And, yes, it has a good testing story (unit and behavioural). And, yes, it works in with figwheel to create -a delightful hot-loading development story. And, yes, it has +a powerful hot-loading development story. And, yes, it has fun specialist tooling, and a community, and useful 3rd party libraries. ## Where Do I Go Next? -We haven't looked at much code yet, but **at this point you +**At this point you already know 50% of re-frame.** There's detail to fill in, for sure, but the core concepts, and even basic coding techniques, are now known to you. diff --git a/docs/CodeWalkthrough.md b/docs/CodeWalkthrough.md index abf8c02..d9ea069 100644 --- a/docs/CodeWalkthrough.md +++ b/docs/CodeWalkthrough.md @@ -1,6 +1,16 @@ + + +## Initial Code Walk-through + +At this point in your reading, you are armed with: + - a high level understanding of the 6 domino process (from re-frame's README) + - an understanding of application state (from the previous tutorial) + +In this tutorial, **we'll look at re-frame code**. + -## Table Of Contents +### Table Of Contents - [Initial Code Walk-through](#initial-code-walk-through) - [What Code?](#what-code) @@ -23,14 +33,6 @@ -## Initial Code Walk-through - -At this point in your reading, you are armed with: - - a high level understanding of the 6 domino process (from re-frame's README) - - an understanding of application state (from the previous tutorial) - -In this tutorial, **we'll look at re-frame code**. Finally. - ## What Code? This repo contains an example application called ["simple"](https://github.com/Day8/re-frame/tree/develop/examples/simple), @@ -43,15 +45,25 @@ enough to start coding by yourself. ## What Does It Do? This app: - - displays the current time in a nice big font + - displays the current time in a nice big, colourful font - provides a text input field into which you can type a hex colour code, like "#CCC", for the time display XXX screenshot -XXX How to run it +To run the code: +A. Install Java 8 (http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) +B. Install leiningen (http://leiningen.org/#install) + +1. git clone https://github.com/Day8/re-frame.git +2. cd re-frame/examples/simple +3. lein do clean, figwheel +4. open http://localhost:3449/example.html + + +The source file we'll be reviewing is: +https://github.com/Day8/re-frame/blob/master/examples/simple/src/simpleexample/core.cljs -XXX path to code ## Namespace diff --git a/docs/FAQs/CatchingEventExceptions.md b/docs/FAQs/CatchingEventExceptions.md new file mode 100644 index 0000000..cd934bd --- /dev/null +++ b/docs/FAQs/CatchingEventExceptions.md @@ -0,0 +1,21 @@ + +### Question + +How can I detect exceptions in Event Handlers? + +### Answer + +A suggested solution can be found in [this issue](https://github.com/Day8/re-frame/issues/231#issuecomment-249991378). + +*** + +Up: [FAQ Index](README.md)       + + + + + + --> diff --git a/docs/FAQs/README.md b/docs/FAQs/README.md index 6a73c92..d39d602 100644 --- a/docs/FAQs/README.md +++ b/docs/FAQs/README.md @@ -3,7 +3,7 @@ ## Table Of Contents - [Frequently Asked Questions](#frequently-asked-questions) - - [Want To Add An FAQ?](#want-to-add-an-faq) +- [Want To Add An FAQ?](#want-to-add-an-faq) @@ -14,10 +14,10 @@ 3. [Dispatched Events Are Null](Null-Dispatched-Events.md) 4. [Why implement re-frame in `.cljc` files](Why-CLJC.md) 5. [Why do we need to clear the subscription cache when reloading with Figwheel?](Why-Clear-Sub-Cache.md) +6. [How can I detect exceptions in Event Handlers?](CatchingEventExceptions.md) - -### Want To Add An FAQ? +## Want To Add An FAQ? We'd like that. Please supply a PR. Or just open an issue. Many Thanks!!