             :response-format :json
             :keywords? true})
       (go-loop []
-        (let [{:keys [dropdown-chan]} (om/get-state owner)
-              {:keys [path value]}    (<! dropdown-chan)]
-          (om/update! data (into [:selected] path) (reader/read-string value))) ;; value from form is a string
+        (let [{:keys [event-chan]}  (om/get-state owner)
+              {:keys [event value]} (<! event-chan)]
+          (cond
+           (= event :dropdown) (let [{:keys [path value]} value]
+                                 (om/update! data (into [:selected] path) (reader/read-string value)))
+           (= event :alert) (om/update! data :alert value)
+           (= event :fetch-data) (fetch-data data)
+           (= event :clear-form) (clear-form data)))
         (recur)))
     om/IRenderState
-    (render-state [_ {:keys [dropdown-chan]}]
+    (render-state [_ {:keys [event-chan]}]
       (let [role (-> data :user :role)
             {:keys [username projects programmes]} (-> data :user)
             selected   (-> data :selected)

         [:div.col-md-12 {:style {:padding-top "10px"}}
          (if editing
            [:div
             ;; Username
             [:div
              [:div.col-md-4
               (om/build (username-selection-form data) (:user data))]
              (when (seq username)
                [:button.btn.btn-primary {:on-click #(post-form data username @selected)} "Save"])]
             ;; Alert
             [:div {:style {:padding-top "10px"}} (om/build bs/alert (:alert data))]
             ;; Admin Role - only visible to super admins
             (when (and (= "super-admin" (:role editor)) (not (nil? role)))
               [:div.form-group.col-md-6
                [:label.control-label.col-md-2 {:for "role-selection"} "Role:"]
                [:div.col-md-6
                 [:div {:style {:width "100%"}}
                  (om/build dropdown {:default role
                                      :items user-roles}
                            {:opts {:dropdown-chan dropdown-chan
                                    :id "role-selection"
                                    :path [:role]}})]]])

             ;; Programmes
             [:div.col-md-12 {:style {:padding-top "15px"}}
              [:h4 "All Programmes"]
              (om/build programmes-table {:programmes (-> data :programmes :data)
                                          :existing-selections (-> data :user :programmes)}
                        {:opts {:dropdown-chan dropdown-chan}})]
             ;; Projects
             [:div.col-md-12
              [:h4 "All Projects"]
              (om/build projects-table {:projects (-> data :projects :data)
                                        :existing-selections (-> data :user :projects)}
                        {:opts {:dropdown-chan dropdown-chan}})]]

            [:div.col-md-12
             [:div.col-md-12 [:div.alert.alert-success {:role "alert"} "User updated successfully."]

       [:label.control-label.col-md-2 {:for label} label]
       [:p {:class "form-control-static col-md-10"} data]]))))

(defn fetch-data [data]
  (data/fetch-programmes data)
  (fetch-projects data))

(defn clear-form
  "Reset app-state when user deletes their selection."
  [data]
  (om/update! data [:programmes :data] [])
  (om/update! data [:projects :data] [])
  (om/update! data :selected nil)
  (om/update! data [:user :role] nil)
  (om/update! data [:user :class] "")
  (om/update! data [:user :username] nil)
  (om/update! data [:user :projects] {})
  (om/update! data [:user :programmes] {}))

(defn user-management-view [data owner]
  (reify
    om/IInitState
    (init-state [_]
      {:event-chan (chan)})
    om/IWillMount
    (will-mount [_]
      (data/fetch-usernames data)
