diff options
author | Stefan Malzner <stefan@adlk.io> | 2017-10-13 12:29:40 +0200 |
---|---|---|
committer | Stefan Malzner <stefan@adlk.io> | 2017-10-13 12:29:40 +0200 |
commit | 58cda9cc7fb79ca9df6746de7f9662bc08dc156a (patch) | |
tree | 1211600c2a5d3b5f81c435c6896618111a611720 /src/stores/lib/Request.js | |
download | ferdium-app-58cda9cc7fb79ca9df6746de7f9662bc08dc156a.tar.gz ferdium-app-58cda9cc7fb79ca9df6746de7f9662bc08dc156a.tar.zst ferdium-app-58cda9cc7fb79ca9df6746de7f9662bc08dc156a.zip |
initial commit
Diffstat (limited to 'src/stores/lib/Request.js')
-rw-r--r-- | src/stores/lib/Request.js | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/src/stores/lib/Request.js b/src/stores/lib/Request.js new file mode 100644 index 000000000..4a6925cc5 --- /dev/null +++ b/src/stores/lib/Request.js | |||
@@ -0,0 +1,112 @@ | |||
1 | import { observable, action, computed } from 'mobx'; | ||
2 | import { isEqual } from 'lodash/fp'; | ||
3 | |||
4 | export default class Request { | ||
5 | static _hooks = []; | ||
6 | |||
7 | static registerHook(hook) { | ||
8 | Request._hooks.push(hook); | ||
9 | } | ||
10 | |||
11 | @observable result = null; | ||
12 | @observable error = null; | ||
13 | @observable isExecuting = false; | ||
14 | @observable isError = false; | ||
15 | @observable wasExecuted = false; | ||
16 | |||
17 | _promise = Promise; | ||
18 | _api = {}; | ||
19 | _method = ''; | ||
20 | _isWaitingForResponse = false; | ||
21 | _currentApiCall = null; | ||
22 | |||
23 | constructor(api, method) { | ||
24 | this._api = api; | ||
25 | this._method = method; | ||
26 | } | ||
27 | |||
28 | execute(...callArgs) { | ||
29 | // Do not continue if this request is already loading | ||
30 | if (this._isWaitingForResponse) return this; | ||
31 | |||
32 | if (!this._api[this._method]) { | ||
33 | throw new Error(`Missing method <${this._method}> on api object:`, this._api); | ||
34 | } | ||
35 | |||
36 | // This timeout is necessary to avoid warnings from mobx | ||
37 | // regarding triggering actions as side-effect of getters | ||
38 | setTimeout(action(() => { | ||
39 | this.isExecuting = true; | ||
40 | }), 0); | ||
41 | |||
42 | // Issue api call & save it as promise that is handled to update the results of the operation | ||
43 | this._promise = new Promise((resolve, reject) => { | ||
44 | this._api[this._method](...callArgs) | ||
45 | .then((result) => { | ||
46 | setTimeout(action(() => { | ||
47 | this.result = result; | ||
48 | if (this._currentApiCall) this._currentApiCall.result = result; | ||
49 | this.isExecuting = false; | ||
50 | this.isError = false; | ||
51 | this.wasExecuted = true; | ||
52 | this._isWaitingForResponse = false; | ||
53 | this._triggerHooks(); | ||
54 | resolve(result); | ||
55 | }), 1); | ||
56 | return result; | ||
57 | }) | ||
58 | .catch(action((error) => { | ||
59 | setTimeout(action(() => { | ||
60 | this.error = error; | ||
61 | this.isExecuting = false; | ||
62 | this.isError = true; | ||
63 | this.wasExecuted = true; | ||
64 | this._isWaitingForResponse = false; | ||
65 | this._triggerHooks(); | ||
66 | reject(error); | ||
67 | }), 1); | ||
68 | })); | ||
69 | }); | ||
70 | |||
71 | this._isWaitingForResponse = true; | ||
72 | this._currentApiCall = { args: callArgs, result: null }; | ||
73 | return this; | ||
74 | } | ||
75 | |||
76 | reload() { | ||
77 | return this.execute(...this._currentApiCall.args); | ||
78 | } | ||
79 | |||
80 | isExecutingWithArgs(...args) { | ||
81 | return this.isExecuting && this._currentApiCall && isEqual(this._currentApiCall.args, args); | ||
82 | } | ||
83 | |||
84 | @computed get isExecutingFirstTime() { | ||
85 | return !this.wasExecuted && this.isExecuting; | ||
86 | } | ||
87 | |||
88 | then(...args) { | ||
89 | if (!this._promise) throw new Error('You have to call Request::execute before you can access it as promise'); | ||
90 | return this._promise.then(...args); | ||
91 | } | ||
92 | |||
93 | catch(...args) { | ||
94 | if (!this._promise) throw new Error('You have to call Request::execute before you can access it as promise'); | ||
95 | return this._promise.catch(...args); | ||
96 | } | ||
97 | |||
98 | _triggerHooks() { | ||
99 | Request._hooks.forEach(hook => hook(this)); | ||
100 | } | ||
101 | |||
102 | reset() { | ||
103 | this.result = null; | ||
104 | this.isExecuting = false; | ||
105 | this.isError = false; | ||
106 | this.wasExecuted = false; | ||
107 | this._isWaitingForResponse = false; | ||
108 | this._promise = Promise; | ||
109 | |||
110 | return this; | ||
111 | } | ||
112 | } | ||