All Projects → day8 → Re Frame Http Fx

day8 / Re Frame Http Fx

Licence: mit
A re-frame "effects handler" for performing Ajax tasks (via cljs-ajax)

Programming Languages

clojure
4091 projects

Labels

Projects that are alternatives of or similar to Re Frame Http Fx

Re Frame
A ClojureScript framework for building user interfaces, leveraging React
Stars: ✭ 4,980 (+2480.31%)
Mutual labels:  re-frame
Hugit
The humane Terminal UI for git!
Stars: ✭ 49 (-74.61%)
Mutual labels:  re-frame
Re Frame Test
Cross platform (cljs and clj) utilities for testing re-frame applications
Stars: ✭ 83 (-56.99%)
Mutual labels:  re-frame
Re Com
A ClojureScript library of reusable components for Reagent
Stars: ✭ 690 (+257.51%)
Mutual labels:  re-frame
Re Frame Forward Events Fx
A re-frame effects handler for listening-for and then post-processing dispatched events
Stars: ✭ 30 (-84.46%)
Mutual labels:  re-frame
Re Navigate
Example of React Native Navigation with re-frame/re-natal
Stars: ✭ 61 (-68.39%)
Mutual labels:  re-frame
Re Frame Template
A Leiningen template for creating a re-frame application (client only)
Stars: ✭ 454 (+135.23%)
Mutual labels:  re-frame
Re Frame Async Flow Fx
A re-frame effects handler for coordinating the kind of async control flow which often happens on app startup.
Stars: ✭ 150 (-22.28%)
Mutual labels:  re-frame
Re Frame Storage
re-frame interceptors for browser local storage
Stars: ✭ 44 (-77.2%)
Mutual labels:  re-frame
Keycloak Clojure
A Clojure library helping the integration of Keycloak with a Clojure Application + a sample SPA Client and API Server demonstrating the Keycloak integration
Stars: ✭ 81 (-58.03%)
Mutual labels:  re-frame
Re Frame Cookie Fx
Om nom nom nom.
Stars: ✭ 17 (-91.19%)
Mutual labels:  re-frame
Re Pollsive
Re-pollsive is a clojurescript library that handles polling events for re-frame applications
Stars: ✭ 27 (-86.01%)
Mutual labels:  re-frame
Subgraph
Reactive graph database for re-frame
Stars: ✭ 63 (-67.36%)
Mutual labels:  re-frame
Cljfx
Declarative, functional and extensible wrapper of JavaFX inspired by better parts of react and re-frame
Stars: ✭ 624 (+223.32%)
Mutual labels:  re-frame
Ventas
Clojure ecommerce platform
Stars: ✭ 114 (-40.93%)
Mutual labels:  re-frame
Re Frame 10x
A debugging dashboard for re-frame. X-ray vision as tooling.
Stars: ✭ 491 (+154.4%)
Mutual labels:  re-frame
Re Frame Undo
An undo library for re-frame
Stars: ✭ 50 (-74.09%)
Mutual labels:  re-frame
Boodle
Accounting SPA in Clojure and ClojureScript
Stars: ✭ 183 (-5.18%)
Mutual labels:  re-frame
Mecca
Animated music editor in Clojurescript/re-frame
Stars: ✭ 125 (-35.23%)
Mutual labels:  re-frame
Gorilla Notebook
A clojure/clojurescript notebook application/-library based on Gorilla-REPL
Stars: ✭ 73 (-62.18%)
Mutual labels:  re-frame

CI CD GitHub tag (latest by date) Clojars Project GitHub issues GitHub pull requests License

HTTP Effects Handler For re-frame

This re-frame library contains an HTTP Effect Handler.

Keyed :http-xhrio, it wraps the goog xhrio API of cljs-ajax.

IMPORTANT: This effect handler depends entirely on the API of cljs-ajax. Make sure you are familiar with the API for cljs-ajax, and especially with ajax-request before proceeding.

Quick Start Guide

Step 1. Add Dependency

Add the following project dependency:
clojars

Requires re-frame >= 0.8.0

Step 2. Registration And Use

In the namespace where you register your event handlers, perhaps called events.cljs, you have 2 things to do.

First, add this "require" to the ns:

(ns app.core
  (:require
    ...
    [day8.re-frame.http-fx]   ;; <-- add this
    ...))

Because we never subsequently use this require, it appears redundant. But its existence will cause the :http-xhrio effect handler to self-register with re-frame, which is important to everything that follows.

Second, write a an event handler which uses this effect:

(ns app.events              ;; or where ever you define your event handlers
  (:require
    ...
    [ajax.core :as ajax]    ;; so you can use this in the response-format below
    ...))
    
(reg-event-fx                             ;; note the trailing -fx
  :handler-with-http                      ;; usage:  (dispatch [:handler-with-http])
  (fn [{:keys [db]} _]                    ;; the first param will be "world"
    {:db   (assoc db :show-twirly true)   ;; causes the twirly-waiting-dialog to show??
     :http-xhrio {:method          :get
                  :uri             "https://api.github.com/orgs/day8"
                  :timeout         8000                                           ;; optional see API docs
                  :response-format (ajax/json-response-format {:keywords? true})  ;; IMPORTANT!: You must provide this.
                  :on-success      [:good-http-result]
                  :on-failure      [:bad-http-result]}}))

Look at the :http-xhrio line above. This library defines the "effects handler" which implements :http-xhrio.

The supplied value should be an options map as defined by the simple interface ajax-request see: api docs. Except for :on-success and :on-failure. All options supported by ajax-request should be supported by this library, as it is a thin wrapper over ajax-request.

Here is an example of a POST request. Note that :format also needs to be specified (unless you pass :body in the map).

(re-frame/reg-event-fx
  ::http-post
  (fn [_world [_ val]]
    {:http-xhrio {:method          :post
                  :uri             "https://httpbin.org/post"
                  :params          data
                  :timeout         5000
                  :format          (ajax/json-request-format)
                  :response-format (ajax/json-response-format {:keywords? true})
                  :on-success      [::success-post-result]
                  :on-failure      [::failure-post-result]}}))

N.B.: ajax-request is harder to use than the GET and POST functions cljs-ajax provides, but this gives you smaller code sizes from dead code elimination. In particular, you MUST provide a :response-format, it is not inferred for you.

Don't provide:

 :api     - the effects handler explicitly uses xhrio so it will be ignored.
 :handler - we substitute this with one that dispatches `:on-success` or `:on-failure` events.

You can also pass a list or vector of these options maps where multiple HTTPs are required.

To make multiple requests, supply a vector of options maps:

{:http-xhrio [ {...}
               {...}]}

Step 3a. Handling :on-success

Provide normal re-frame handlers for :on-success and :on-failure. Your event handlers will get the result as the last argument of their event vector. Here is an example written as another effect handler to put the result into db.

(reg-event-db
  ::success-http-result
  (fn [db [_ result]]
    (assoc db :success-http-result result)))

Step 3b. Handling :on-failure

The result supplied to your :on-failure handler will be a map containing various xhrio details (details below). See the fn ajax-xhrio-handler for details

Step 3.1 :on-failure result

A simple failure handler could be written this way ...

(reg-event-db
  ::failure-http-result
  (fn [db [_ result]]
    ;; result is a map containing details of the failure
    (assoc db :failure-http-result result)))
status of 40x/50x

If the network connection to the server is successful, but the server returns an error (40x/50x) HTTP status code result will be a map like:

{:uri "/error"
 :last-method "GET"
 :last-error "Service Unavailable [503]"
 :last-error-code 6
 :debug-message "Http response at 400 or 500 level"
 :status 503
 :status-text "Service Unavailable"
 :failure :error
 :response nil}
Status 0

In some cases, if the network connection itself is unsuccessful, it is possible to get a status code of 0. For example:

  • cross-site scripting whereby access is denied; or
  • requesting a URI that is unreachable (typo, DNS issues, invalid hostname etc); or
  • request is interrupted after being sent (browser refresh or navigates away from the page); or
  • request is otherwise intercepted (check your ad blocker).

In this case, result will be something like:

{:uri "http://i-do-not-exist/error"
 :last-method "GET"
 :last-error " [0]"
 :last-error-code 6
 :debug-message "Http response at 400 or 500 level"
 :status 0
 :status-text "Request failed."
 :failure :failed}
Status -1

If the time for the sever to respond exceeds :timeout result will be a map something like:

{:uri "/timeout"
 :last-method "GET"
 :last-error "Timed out after 1ms, aborting"
 :last-error-code 8
 :debug-message "Request timed out"
 :status -1
 :status-text "Request timed out."
 :failure :timeout}

Optional: Handler for :on-request

If you need access to the raw request, to for example, cancel long running requests or repeated debounced requests, you can pass an :on-request handler that will be called with the request.

(re-frame/reg-event-fx
  ::http-post
  (fn [_world [_ val]]
    {:http-xhrio {:method          :get
                  :uri             "https://httpbin.org/delay/60"
                  :format          (ajax/json-request-format)
                  :response-format (ajax/json-response-format {:keywords? true})
                  :on-request      [::track-slow-request "my-request"]
                  :on-success      [::success-get-result]
                  :on-failure      [::failure-get-result]}}))

(reg-event-db
  ::track-slow-request
  (fn [db [_ my-id xhrio]]
    (assoc-in db [:requests my-id] xhrio)))

Later if you need to, you could retrieve the request from the app-db and cancel it.

N.B.: To prevent memory leaks you need to cleanup the request in both your :on-success and :on-failure handlers. Otherwise the requests will just hang around in your app-db indefinitely.

Tip

If you need additional arguments or identifying tokens in your handler, then include them in your :on-success and :on-failure event vector in Step 3.

For example ...

(re-frame/reg-event-fx
  ::http-post
  (fn [_ [_ val]]
    {:http-xhrio {:method          :post
                  ...
                  :on-success      [::success-post-result 42 "other"]
                  :on-failure      [::failure-post-result :something :else]}}))

Notice the way that additional values are encoded into the success and failure event vectors.

These event vectors will be dispatched (result is conj-ed to the end) making all encoded values AND the result available to the handlers.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].