Browse Source

#1 Change progress API usage

Ben Hsieh 8 years ago
parent
commit
2a5f183aad
3 changed files with 64 additions and 13 deletions
  1. 44
    5
      src/README.md
  2. 19
    7
      src/index.js
  3. 1
    1
      src/package.json

+ 44
- 5
src/README.md View File

1
 # react-native-fetch-blob [![npm version](https://badge.fury.io/js/react-native-fetch-blob.svg)](https://badge.fury.io/js/react-native-fetch-blob)
1
 # react-native-fetch-blob [![npm version](https://badge.fury.io/js/react-native-fetch-blob.svg)](https://badge.fury.io/js/react-native-fetch-blob)
2
 
2
 
3
-A react-native module for fetch file/image with custom headers, supports blob response data.
3
+A react-native module for fetch file/image with custom headers, supports blob response data, and upload/download progress.
4
 
4
 
5
 If you're dealing with image or file server that requires an `Authorization` token in the header, or you're having problem with `fetch` API when receiving blob data, you might try this module (this is also the reason why I made this).
5
 If you're dealing with image or file server that requires an `Authorization` token in the header, or you're having problem with `fetch` API when receiving blob data, you might try this module (this is also the reason why I made this).
6
 
6
 
10
 
10
 
11
 The source code is very simple, just an implementation of native HTTP request, supports both Android (uses awesome native library  [AsyncHttpClient](https://github.com/AsyncHttpClient/async-http-client])) and IOS.
11
 The source code is very simple, just an implementation of native HTTP request, supports both Android (uses awesome native library  [AsyncHttpClient](https://github.com/AsyncHttpClient/async-http-client])) and IOS.
12
 
12
 
13
+## Major Changes
14
+
15
+| Version | |
16
+|---|---|
17
+| 0.3 | Upload/Download octet-stream and form-data |
18
+| 0.4 | Add base-64 encode/decode library and API |
19
+| 0.4.1 | Fixe upload form-data missing file extension problem on Android |
20
+| 0.4.2 | Supports upload/download progress |
21
+
13
 ## Usage
22
 ## Usage
14
 
23
 
15
 * [Installation](#user-content-installation)
24
 * [Installation](#user-content-installation)
17
  * [Download file](#user-content-download-example--fetch-files-that-needs-authorization-token)
26
  * [Download file](#user-content-download-example--fetch-files-that-needs-authorization-token)
18
  * [Upload file](#user-content-upload-example--dropbox-files-upload-api)
27
  * [Upload file](#user-content-upload-example--dropbox-files-upload-api)
19
  * [Multipart/form upload](#user-content-multipartform-data-example--post-form-data-with-file-and-data)
28
  * [Multipart/form upload](#user-content-multipartform-data-example--post-form-data-with-file-and-data)
29
+ * [Upload/Download progress](#user-content-uploaaddownload-progress)
20
 * [API](#user-content-api)
30
 * [API](#user-content-api)
21
 
31
 
22
 ## Installation
32
 ## Installation
114
   })
124
   })
115
 ```
125
 ```
116
 
126
 
127
+#### Upload/Download progress
128
+
129
+In `version >= 0.4.2` it is possible to know the upload/download progress.
130
+
131
+```js
132
+  RNFetchBlob.fetch('POST', 'http://www.example.com/upload', {
133
+      ... some headers,
134
+      'Content-Type' : 'octet-stream'
135
+    }, base64DataString)
136
+    .progress((received, total) => {
137
+        console.log('progress', received / total)
138
+    })
139
+    .then((resp) => {
140
+      // ...
141
+    })
142
+    .catch((err) => {
143
+      // ...
144
+    })
145
+```
146
+
147
+
117
 ## API
148
 ## API
118
 
149
 
119
-#### `fetch(method, url, headers, body):Promise<FetchBlobResponse> `
150
+#### `fetch(method, url, headers, body):Promise<FetchBlobResponse>`
120
 
151
 
121
 Send a HTTP request uses given headers and body, and return a Promise.
152
 Send a HTTP request uses given headers and body, and return a Promise.
122
 
153
 
128
 Headers of HTTP request, value of headers should be `stringified`, if you're uploading binary files, content-type should be `application/octet-stream` or `multipart/form-data`(see examples above).
159
 Headers of HTTP request, value of headers should be `stringified`, if you're uploading binary files, content-type should be `application/octet-stream` or `multipart/form-data`(see examples above).
129
 #### body:`string | Array<Object>` (Optional)
160
 #### body:`string | Array<Object>` (Optional)
130
 Body of the HTTP request, body can either be a BASE64 string, or an array contains object elements, each element have 2  required property `name`, and `data`, and 1 optional property `filename`, once `filename` is set, content in `data` property will be consider as BASE64 string that will be converted into byte array later.
161
 Body of the HTTP request, body can either be a BASE64 string, or an array contains object elements, each element have 2  required property `name`, and `data`, and 1 optional property `filename`, once `filename` is set, content in `data` property will be consider as BASE64 string that will be converted into byte array later.
131
-
132
 When body is a base64 string , this string will be converted into byte array in native code, and the request body will be sent as `application/octet-stream`.
162
 When body is a base64 string , this string will be converted into byte array in native code, and the request body will be sent as `application/octet-stream`.
133
 
163
 
164
+### `fetch(...).progress(eventListener):Promise<FetchBlobResponse>` added in `0.4.2`
165
+
166
+Register on progress event handler for a fetch request.
167
+
168
+#### eventListener:`(sendOrReceivedBytes:number, totalBytes:number)`
169
+
170
+A function that triggers when there's data received/sent, first argument is the number of sent/received bytes, and second argument is expected total bytes number.
171
+
134
 #### `base64`
172
 #### `base64`
135
 
173
 
136
 A helper object simply uses [base-64](https://github.com/mathiasbynens/base64) for decode and encode BASE64 data.
174
 A helper object simply uses [base-64](https://github.com/mathiasbynens/base64) for decode and encode BASE64 data.
152
   returns decoded base64 string (done in js context)
190
   returns decoded base64 string (done in js context)
153
 
191
 
154
 
192
 
155
-### TODO
193
+### Upcoming Features
156
 
194
 
157
-* Save file to storage
195
+* Save file to storage directly
196
+* Upload file from storage directly
158
 * Custom MIME type in form data
197
 * Custom MIME type in form data

+ 19
- 7
src/index.js View File

1
 /**
1
 /**
2
  * @author wkh237
2
  * @author wkh237
3
- * @version 0.3.3
3
+ * @version 0.4.2
4
  */
4
  */
5
 
5
 
6
 import {
6
 import {
15
 const RNFetchBlob = NativeModules.RNFetchBlob
15
 const RNFetchBlob = NativeModules.RNFetchBlob
16
 
16
 
17
 // Show warning if native module not detected
17
 // Show warning if native module not detected
18
-if(RNFetchBlob === void 0) {
18
+if(!RNFetchBlob || !RNFetchBlob.fetchBlobForm || !RNFetchBlob.fetchBlob) {
19
   console.warn(
19
   console.warn(
20
-    'react-native-fetch-blob could not find native module.',
20
+    'react-native-fetch-blob could not find valid native module.',
21
     'please make sure you have linked native modules using `rnpm link`,',
21
     'please make sure you have linked native modules using `rnpm link`,',
22
     'and restart RN packager or manually compile IOS/Android project.'
22
     'and restart RN packager or manually compile IOS/Android project.'
23
   )
23
   )
24
 }
24
 }
25
 
25
 
26
+const config = function(options) {
27
+  return { fetch : fetch.bind(options) }
28
+}
29
+
26
 // Promise wrapper function
30
 // Promise wrapper function
27
-const fetch = (...args) => {
31
+const fetch = function(...args) {
32
+
33
+  let options = this || {}
28
 
34
 
29
   // create task ID for receiving progress event
35
   // create task ID for receiving progress event
30
   let taskId = getUUID()
36
   let taskId = getUUID()
37
+
31
   let promise = new Promise((resolve, reject) => {
38
   let promise = new Promise((resolve, reject) => {
32
 
39
 
33
     let [method, url, headers, body] = [...args]
40
     let [method, url, headers, body] = [...args]
34
     let nativeMethodName = Array.isArray(body) ? 'fetchBlobForm' : 'fetchBlob'
41
     let nativeMethodName = Array.isArray(body) ? 'fetchBlobForm' : 'fetchBlob'
42
+
43
+    // on progress event listener
35
     let subscription = emitter.addListener('RNFetchBlobProgress', (e) => {
44
     let subscription = emitter.addListener('RNFetchBlobProgress', (e) => {
36
       if(e.taskId === taskId && promise.onProgress) {
45
       if(e.taskId === taskId && promise.onProgress) {
37
         promise.onProgress(e.written, e.total)
46
         promise.onProgress(e.written, e.total)
38
       }
47
       }
39
     })
48
     })
40
 
49
 
41
-    RNFetchBlob[nativeMethodName](taskId, method, url, headers || {}, body, (err, ...data) => {
50
+    let req = RNFetchBlob[nativeMethodName]
51
+    req(taskId, method, url, headers || {}, body, (err, ...data) => {
42
 
52
 
43
       // task done, remove event listener
53
       // task done, remove event listener
44
       subscription.remove()
54
       subscription.remove()
45
-
46
       if(err)
55
       if(err)
47
         reject(new Error(err, ...data))
56
         reject(new Error(err, ...data))
48
       else
57
       else
52
 
61
 
53
   })
62
   })
54
 
63
 
55
-  promise.onProgress = null
64
+  promise.progress = (fn) => {
65
+    promise.onProgress = fn
66
+    return promise
67
+  }
56
 
68
 
57
   return promise
69
   return promise
58
 
70
 

+ 1
- 1
src/package.json View File

1
 {
1
 {
2
   "name": "react-native-fetch-blob",
2
   "name": "react-native-fetch-blob",
3
-  "version": "0.4.1",
3
+  "version": "0.4.2",
4
   "description": "A react-native plugin for fetch blob data via HTTP.",
4
   "description": "A react-native plugin for fetch blob data via HTTP.",
5
   "main": "index.js",
5
   "main": "index.js",
6
   "scripts": {
6
   "scripts": {