Search code examples
clojurescriptom

Writing a structured Om application with requests, but not om.next


I'd like to write an application in Om - a GitHub issues viewer in particular. To retrieve issues from GitHub, I'll need to XHR request them, and there'll be the action of marking issues as 'viewed' by sending a request back to GitHub.

There's quite a bit of documentation for using the current version of Om without async/http calls, and quite a bit for using Om.next with them, but I'm just getting started and feel like Om.next isn't the right place for a complete ClojureScript newbie to dive in.

Is there documentation and are there patterns for using the current stable version of Om (0.8.x) with remote resources, that'd lead to a clean architecture for this kind of app? The big applications that are using Om in production, like CircleCI - are they using Om.next? If not, what's the commonly-accepted pattern for requests?


Solution

  • I think, that you can dive in om's real-world example. They are using Google Closure's XhrIo for async http calls.

    (defn edn-xhr [{:keys [method url data on-complete]}]
      (let [xhr (XhrIo.)]
        (events/listen xhr goog.net.EventType.COMPLETE
          (fn [e]
            (on-complete (reader/read-string (.getResponseText xhr)))))
        (. xhr
          (send url (meths method) (when data (pr-str data))
            #js {"Content-Type" "application/edn"}))))
    

    Communicating server on user change

    (defn on-edit [id title]
      (edn-xhr
        {:method :put
         :url (str "class/" id "/update")
         :data {:class/title title}
         :on-complete
         (fn [res]
           (println "server response:" res))}))
    

    Data loading on om.core/IWillMount

    (defn classes-view [app owner]
      (reify
        om/IWillMount
        (will-mount [_]
          (edn-xhr
            {:method :get
             :url "classes"
             :on-complete #(om/transact! app :classes (fn [_] %))}))
        om/IRender
        (render [_]
          (dom/div #js {:id "classes"}
            (dom/h2 nil "Classes")
            (apply dom/ul nil
              (map
                (fn [class]
                  (let [id (:class/id class)]
                    (om/build editable class
                      {:opts {:edit-key :class/title
                              :on-edit #(on-edit id %)}})))
                (:classes app)))))))
    

    This is not answer for your question, but you can dive in om examples