   The only difference is that `load-data` must be passed a complete query while `load-field` uses the passed-in component
   to create its query.
 
-  So, `load-field` focuses the component's query to the specified field, associates the component's ident with the query,
+  `load-field` is really just a helper for a common use-case: loading a field of some specific thing on the screen. It
+   focuses the component's query to the specified field, associates the component's ident with the query,
   and asks the UI to re-render all components with the calling component's ident after the load is complete. Since `load-field`
-  requires a component to build the query sent to the server, it cannot be used with the reconciler. If you want to load data
+  requires a component to build the query sent to the server it cannot be used with the reconciler. If you want to load data
   from your server when the app initially loads, you must use `load-data` with the reconciler passed to the
   `:started-callback` function when creating a new untangled client application.
 

(ns untangled-tutorial.H-Server-Interactions
  (:require-macros [cljs.test :refer [is]])
  (:require [om.next :as om :refer-macros [defui]]
            [om.dom :as dom]
            [devcards.core :as dc :refer-macros [defcard defcard-doc]]))

; TODO: Explain Om's HATEOS (keyword listing in :keys)
; see: https://github.com/omcljs/om/wiki/Quick-Start-%28om.next%29

      not asked for alone). This does indicate that your UI is possibly in a state inconsistent with the server, which
      is the reason for the \"avoid this case\" advice.

  #### Normalization

  Normalization is always *on* in Untangled because your application will not work correctly if you don't normalize the
  data in your database. Loads must use real composed queries from the UI for normalization to work (the om `get-query` function adds info to assit
  with normalization).

  Therefore, you almost *never* want to use a hand-written query that has not been placed on a `defui`. It is perfectly
  acceptable to define queries via `defui` to ensure normalization will work, and this will commonly be the case if your
  UI needs to ask for data in a structure different from what you want to run against the server.

  For example, say we have some items in our database, and we're planning on showing them grouped by category. We *could*
  write a server-side handler that could return them this way, but the grouping in the UI is really more of a UI
  concern (we might also want them sorted by name, etc, etc.). It makes a lot more sense to define a single server-side
  query that can return the items we want, and then define a UI-side transformation to run as a post-mutation that
  forms them into the desired structure for the UI.

  So, we need the data in our client database (normalized), but our UI might only have queries related to the grouped
  view. Thus, we don't have a UI query that meets our server query needs.

  In this situation we could write the following query-and-ident-only components:
  "
  (dc/mkdn-pprint-source ItemQuery)
  (dc/mkdn-pprint-source CategoryQuery)
  "

  The proper way to now ask the server would be to do something like join this query into a top-level key:

  "
  (dc/mkdn-pprint-source component-query)
  "

  The resulting query, if you were to ask for it with `om/get-query` would look the same as this hand-written
  query:

  "
  (dc/mkdn-pprint-source hand-written-query)
  "
  However, if you were to use the hand-written query then Om would not know how to normalize the server result
  into your database because the Ident functions would not be known (the `get-query` function adds metadata to
  the query to tell Om how to normalize the result`).

  The following card demonstrates the difference of merging the following server response: "
  (dc/mkdn-pprint-source sample-server-response))

(defn merge-using-query [state-atom query data]
  (let [db (om/tree->db query data true)]
    (swap! state-atom assoc :resulting-database db)))

(defcard query-response-demo
  "This card shows the difference between using hand-written queries and queries pulled from
  defui components (which need not have UI)."
  (fn [state-atom _]
    (dom/div nil
      (dom/button #js {:onClick #(merge-using-query state-atom hand-written-query sample-server-response)} "Merge with Hand-Written Query")
      (dom/button #js {:onClick #(merge-using-query state-atom component-query sample-server-response)} "Merge with Component Query")))
  {}
  {:inspect-data true})

(defcard-doc
  "
  and now perhaps you can see the true power of Untangled's approach to data loading! One server query implementation
  can now serve any of your needs for displaying these items.

  #### Post Mutations

  We've seen the power of using component to generate queries that are simple for the server (even though the UI might
  want to display the result in a more complex way). Now, we'll finish the example by showing you how post mutations
  can complete the story (and for Om users, complete your understanding of why a custom parser isn't necessary in Untangled).

  In the prior section we talked about obtaining items that have categories. We wanted a simple server query so that
  obtaining the items was the same no matter what kind of UI was going to use them (a display of items grouped by category,
  for example).

  ```text
  Simple Query Result from Server
              |
     auto merge/normalize
              |
             \\|/
      Items with Categories
              |
         post mutation
              |
             \\|/
      Items by Category
  ```

  We all understand doing these kinds of transforms, so this technique gives some real concrete advantages overall:

  - Simple query to the server (only have to write one query handler)
      - Independent of the server's database structure (do items belong to categories, or just have them, etc).
  - Simple layout in resulting UI database (normalized into tables and a graph)
  - Straightforward data transform into what we want to show

  So, let's add in the idea that the UI really wants to show a Toolbar that contains the items
  grouped by category, but our sample load is as before.

  The Untangled post-mutation can defined as:

  ```clojure
  (defmethod m/mutate 'server-interaction/group-items [{:keys [state]} k p]
    {:action (fn [] (swap! state group-items))})
  ```

  Where the UI components and helper functions are:

  "
  (dc/mkdn-pprint-source ToolbarItem)
  (dc/mkdn-pprint-source ToolbarCategory)
  (dc/mkdn-pprint-source Toolbar)
  (dc/mkdn-pprint-source add-to-category)
  (dc/mkdn-pprint-source group-items))

(defcard toolbar-with-items-by-category
  "This card allows you to simulate the post-mutation defined above, and see the resulting UI and database change. The
  Reset button will restore the db to the pre-mutation state, so you can A/B compare the before and after picture."
  (untangled-app Toolbar)
  (om/tree->db component-query sample-server-response true)
  {:inspect-data true})

(defcard-doc "
  ### Parameterized Reads

  You may add parameters to your remote reads using an optional argument to data fetch:
