add extract option to m.request

This commit is contained in:
Leo Horie 2014-04-19 22:47:03 -04:00
parent cb6994dd93
commit bb54a3b675
8 changed files with 56 additions and 16 deletions

View file

@ -430,11 +430,12 @@ Mithril = m = new function app(window) {
var deferred = m.deferred()
var serialize = xhrOptions.serialize || JSON.stringify
var deserialize = xhrOptions.deserialize || JSON.parse
var extract = xhrOptions.extract || function(xhr, xhrOptions) {return xhr.responseText}
xhrOptions.url = parameterizeUrl(xhrOptions.url, xhrOptions.data)
xhrOptions = bindData(xhrOptions, xhrOptions.data, serialize)
xhrOptions.onload = xhrOptions.onerror = function(e) {
var unwrap = (e.type == "load" ? xhrOptions.unwrapSuccess : xhrOptions.unwrapError) || identity
var response = unwrap(deserialize(e.target.responseText))
var response = unwrap(deserialize(extract(e.target, xhrOptions)))
if (response instanceof Array && xhrOptions.type) {
for (var i = 0; i < response.length; i++) response[i] = new xhrOptions.type(response[i])
}

View file

@ -430,11 +430,12 @@ Mithril = m = new function app(window) {
var deferred = m.deferred()
var serialize = xhrOptions.serialize || JSON.stringify
var deserialize = xhrOptions.deserialize || JSON.parse
var extract = xhrOptions.extract || function(xhr, xhrOptions) {return xhr.responseText}
xhrOptions.url = parameterizeUrl(xhrOptions.url, xhrOptions.data)
xhrOptions = bindData(xhrOptions, xhrOptions.data, serialize)
xhrOptions.onload = xhrOptions.onerror = function(e) {
var unwrap = (e.type == "load" ? xhrOptions.unwrapSuccess : xhrOptions.unwrapError) || identity
var response = unwrap(deserialize(e.target.responseText))
var response = unwrap(deserialize(extract(e.target, xhrOptions)))
if (response instanceof Array && xhrOptions.type) {
for (var i = 0; i < response.length; i++) response[i] = new xhrOptions.type(response[i])
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

View file

@ -213,6 +213,16 @@ var users = User.list();
url: &quot;myfile.txt&quot;,
deserialize: function(value) {return value;}
});</code></pre>
<hr>
<h3 id="extracting-metadata-from-the-response">Extracting Metadata from the Response</h3>
<p>The <code>extract</code> method can be used to read metadata from HTTP response headers or the status field of an XMLHttpRequest.</p>
<pre><code class="lang-javascript">var extract = function(xhr, xhrOptions) {
if (xhrOptions.method == &quot;HEAD&quot;) return xhr.getResponseHeader(&quot;x-item-count&quot;)
else return xhr.responseText
}
m.request({method: &quot;POST&quot;, url: &quot;/foo&quot;, extract: extract});</code></pre>
<hr>
<h3 id="configuring-the-underlying-xmlhttprequest">Configuring the underlying XMLHttpRequest</h3>
<p>The <code>config</code> option can be used to arbitrarily configure the native XMLHttpRequest instance and to access properties that would not be accessible otherwise.</p>
<p>The example below show how to configure a request where the server expects requests to have a <code>Content-Type: application/json</code> header</p>
@ -235,14 +245,14 @@ where:
[String user,]
[String password,]
[Object&lt;any&gt; data,]
[Response unwrapSuccess(Response data),]
[Response unwrapError(Response data),]
[any unwrapSuccess(any data),]
[any unwrapError(any data),]
[String serialize(any dataToSerialize),]
[any deserialize(String dataToDeserialize),]
[any extract(XMLHttpRequest xhr, XHROptions options),]
[void type(Object&lt;any&gt; data),]
[void config(XMLHttpRequest xhr, XHROptions options)]
}
Response :: Object&lt;any&gt; | Array&lt;any&gt;</code></pre>
}</code></pre>
<ul>
<li><p><strong>XHROptions options</strong></p>
<p>A map of options for the XMLHttpRequest</p>
@ -265,7 +275,7 @@ where:
<li><p><strong>Object<any> data</strong> (optional)</p>
<p>Data to be sent. It&#39;s automatically placed in the appropriate section of the request with the appropriate serialization based on <code>method</code></p>
</li>
<li><p><strong>Response unwrapSuccess(Response data)</strong> (optional)</p>
<li><p><strong>any unwrapSuccess(any data)</strong> (optional)</p>
<p>A preprocessor function to extract the data from a success response in case the response contains metadata wrapping the data.</p>
<p>The default value (if this parameter is falsy) is the identity function <code>function(value) {return value}</code></p>
<p>For example, if the response is <code>{data: [{name: &quot;John&quot;}, {name: &quot;Mary&quot;}]}</code> and the unwrap function is <code>function(response) {return response.data}</code>, then the response will be considered to be <code>[{name: &quot;John&quot;}, {name: &quot;Mary&quot;}]</code> when processing the <code>type</code> parameter</p>
@ -278,7 +288,7 @@ where:
</li>
</ul>
</li>
<li><p><strong>String unwrapError(Response data)</strong> (optional)</p>
<li><p><strong>any unwrapError(any data)</strong> (optional)</p>
<p>A preprocessor function to extract the data from an error response in case the response contains metadata wrapping the data.</p>
<p>The default value (if this parameter is falsy) is the identity function <code>function(value) {return value}</code></p>
<ul>
@ -312,6 +322,10 @@ where:
</li>
</ul>
</li>
<li><p><strong>any extract(XMLHttpRequest xhr, XHROptions options)</strong> (optional)</p>
<p>Method to use to extract the data from the raw XMLHttpRequest. This is useful when the relevant data is either in a response header or the status field.</p>
<p>If this parameter is falsy, <code>xhr.responseText</code> will be used.</p>
</li>
<li><p><strong>void type(Object<any> data)</strong> (optional)</p>
<p>The response object (or the child items if this object is an Array) will be passed as a parameter to the class constructor defined by <code>type</code></p>
<p>If this parameter is falsy, the deserialized data will not be wrapped.</p>

View file

@ -226,6 +226,23 @@ var file = m.request({
});
```
---
### Extracting Metadata from the Response
The `extract` method can be used to read metadata from HTTP response headers or the status field of an XMLHttpRequest.
```javascript
var extract = function(xhr, xhrOptions) {
if (xhrOptions.method == "HEAD") return xhr.getResponseHeader("x-item-count")
else return xhr.responseText
}
m.request({method: "POST", url: "/foo", extract: extract});
```
---
### Configuring the underlying XMLHttpRequest
The `config` option can be used to arbitrarily configure the native XMLHttpRequest instance and to access properties that would not be accessible otherwise.
@ -258,14 +275,14 @@ where:
[String user,]
[String password,]
[Object<any> data,]
[Response unwrapSuccess(Response data),]
[Response unwrapError(Response data),]
[any unwrapSuccess(any data),]
[any unwrapError(any data),]
[String serialize(any dataToSerialize),]
[any deserialize(String dataToDeserialize),]
[any extract(XMLHttpRequest xhr, XHROptions options),]
[void type(Object<any> data),]
[void config(XMLHttpRequest xhr, XHROptions options)]
}
Response :: Object<any> | Array<any>
```
- **XHROptions options**
@ -296,7 +313,7 @@ where:
Data to be sent. It's automatically placed in the appropriate section of the request with the appropriate serialization based on `method`
- **Response unwrapSuccess(Response data)** (optional)
- **any unwrapSuccess(any data)** (optional)
A preprocessor function to extract the data from a success response in case the response contains metadata wrapping the data.
@ -312,7 +329,7 @@ where:
The unwrapped data
- **String unwrapError(Response data)** (optional)
- **any unwrapError(any data)** (optional)
A preprocessor function to extract the data from an error response in case the response contains metadata wrapping the data.
@ -349,7 +366,13 @@ where:
Data to be deserialized
- **returns any deserializedData**
- **any extract(XMLHttpRequest xhr, XHROptions options)** (optional)
Method to use to extract the data from the raw XMLHttpRequest. This is useful when the relevant data is either in a response header or the status field.
If this parameter is falsy, `xhr.responseText` will be used.
- **void type(Object<any> data)** (optional)
The response object (or the child items if this object is an Array) will be passed as a parameter to the class constructor defined by `type`

View file

@ -430,11 +430,12 @@ Mithril = m = new function app(window) {
var deferred = m.deferred()
var serialize = xhrOptions.serialize || JSON.stringify
var deserialize = xhrOptions.deserialize || JSON.parse
var extract = xhrOptions.extract || function(xhr, xhrOptions) {return xhr.responseText}
xhrOptions.url = parameterizeUrl(xhrOptions.url, xhrOptions.data)
xhrOptions = bindData(xhrOptions, xhrOptions.data, serialize)
xhrOptions.onload = xhrOptions.onerror = function(e) {
var unwrap = (e.type == "load" ? xhrOptions.unwrapSuccess : xhrOptions.unwrapError) || identity
var response = unwrap(deserialize(e.target.responseText))
var response = unwrap(deserialize(extract(e.target, xhrOptions)))
if (response instanceof Array && xhrOptions.type) {
for (var i = 0; i < response.length; i++) response[i] = new xhrOptions.type(response[i])
}