-
Notifications
You must be signed in to change notification settings - Fork 0
/
axios.cljc
117 lines (104 loc) · 3.27 KB
/
axios.cljc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
(ns deepstate.action.axios
#?(:clj
(:require
[deepstate.action :as-alias action]
[deepstate.action.async :as action.async]))
#?(:cljs
(:require
[promesa.core :as p]
[deepstate.action :as action]
[deepstate.action.async :as action.async]))
#?(:cljs
(:require-macros
[deepstate.action.axios])))
;; you might think that :deepstate.action.api could be required with
;; an :as-alias to shorten the keywords below, but that would require
;; both :clj and :cljs :as-alias statements which compiles just fine,
;; but chokes cljdoc
#?(:cljs
(defn parse-axios-success-response
"parse errored axios API responses"
[{data :data
status :status
content-type :content-type
:as _r}]
{::action/schema :api
:deepstate.action.api/data data
:deepstate.action.api/status status
:deepstate.action.api/content-type content-type}))
#?(:cljs
(defn parse-axios-error-response
"parse successful axios API responses"
[r]
(let [{err-message :message
err-stack :stack
err-code :code
:as err-data} (-> r (.toJSON) (js->clj :keywordize-keys true))]
(p/rejected
{::action/schema :api
:deepstate.action.api/err-message err-message
:deepstate.action.api/err-stack err-stack
:deepstate.action.api/err-code err-code
:deepstate.action.api/org-err err-data}))))
#?(:cljs
(defn handle-axios-response
"parse both axios API response branches"
[api-promise]
(p/handle
api-promise
(fn [succ err]
(if (some? err)
(parse-axios-error-response err)
(parse-axios-success-response succ))))))
#?(:cljs
(defn axios-action-handler
"function to perform an axios-action - an async-action with
response parsing. invoked from expansions of the `def-axios-action` macro"
[key
state
action
axios-promise-fn
init-effects-fn
completion-effects-fn]
(let [async-action-data-promise-fn
(fn [state async-action-state new-async-action-state]
(let [axios-promise (axios-promise-fn
state
async-action-state
new-async-action-state)]
(handle-axios-response axios-promise)))]
(action.async/async-action-handler
key
state
action
async-action-data-promise-fn
init-effects-fn
completion-effects-fn))))
#?(:clj
(defmacro def-axios-action
"define an axios based async action - it's like an
[[deepstate.action.async/def-async-action]] with parsing
of the result of `axios-promise` to make things friendlier"
([key
bindings
axios-promise
init-effects-map
completion-effects-map]
`(action.async/def-async-action-handler
~key
~bindings
~axios-promise
~init-effects-map
~completion-effects-map
axios-action-handler))
([key
bindings
axios-promise
completion-effects-map]
`(action.async/def-async-action-handler
~key
~bindings
~axios-promise
nil
~completion-effects-map
axios-action-handler))))