Skip to content
This repository has been archived by the owner on Mar 13, 2018. It is now read-only.

Commit

Permalink
Fix race condition with response attribute. Fixes #12.
Browse files Browse the repository at this point in the history
There are two use cases as I see it. One is to fire off a series of requests
and react to all of them. The other is to treat all responses but the response to the most recent request as stale (e.g. in a search app you only want to show results for the current search and ignore out of order responses)

This change accomodates both use cases by firing events for every response (
which is unchanged), but setting up the response attribute to be either the
response for the most resent request, or null. Likewise it exposes an error
attribute that behaves the same way.
  • Loading branch information
rictic committed Jul 27, 2014
1 parent 7c827ff commit 509ef7c
Showing 1 changed file with 44 additions and 25 deletions.
69 changes: 44 additions & 25 deletions core-ajax.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
params='{"alt":"json", "q":"chrome"}'
handleAs="json"
on-core-response="{{handleResponse}}"></core-ajax>
With `auto` set to `true`, the element performs a request whenever
its `url` or `params` properties are changed.
Expand All @@ -32,19 +32,19 @@
@homepage github.io
-->
<link rel="import" href="core-xhr.html">
<polymer-element name="core-ajax" hidden attributes="url handleAs auto params response method headers body contentType withCredentials">
<polymer-element name="core-ajax" hidden attributes="url handleAs auto params response error method headers body contentType withCredentials">
<script>

Polymer('core-ajax', {
/**
* Fired when a response is received.
*
*
* @event core-response
*/

/**
* Fired when an error is received.
*
*
* @event core-error
*/

Expand All @@ -56,7 +56,7 @@

/**
* The URL target of the request.
*
*
* @attribute url
* @type string
* @default ''
Expand All @@ -66,21 +66,21 @@
/**
* Specifies what data to store in the `response` property, and
* to deliver as `event.response` in `response` events.
*
*
* One of:
*
*
* `text`: uses `XHR.responseText`.
*
*
* `xml`: uses `XHR.responseXML`.
*
*
* `json`: uses `XHR.responseText` parsed as JSON.
*
* `arraybuffer`: uses `XHR.response`.
*
* `blob`: uses `XHR.response`.
*
* `document`: uses `XHR.response`.
*
*
* @attribute handleAs
* @type string
* @default 'text'
Expand All @@ -98,22 +98,33 @@

/**
* Parameters to send to the specified URL, as JSON.
*
*
* @attribute params
* @type string (JSON)
* @default ''
*/
params: '',

/**
* Returns the response object.
* The response for the most recently made request, or null if it hasn't
* completed yet or the request resulted in error.
*
* @attribute response
* @type Object
* @default null
*/
response: null,

/**
* The error for the most recently made request, or null if it hasn't
* completed yet or the request resulted in success.
*
* @attribute error
* @type Object
* @default null
*/
error: null,

/**
* The HTTP method to use such as 'GET', 'POST', 'PUT', or 'DELETE'.
* Default is 'GET'.
Expand All @@ -129,13 +140,13 @@
*
* Example:
*
* <core-ajax
* <core-ajax
* auto
* url="http://somesite.com"
* headers='{"X-Requested-With": "XMLHttpRequest"}'
* handleAs="json"
* on-core-response="{{handleResponse}}"></core-ajax>
*
*
* @attribute headers
* @type Object
* @default null
Expand All @@ -150,7 +161,7 @@
* <core-ajax method="POST" auto url="http://somesite.com"
* body='{"foo":1, "bar":2}'>
* </core-ajax>
*
*
* @attribute body
* @type Object
* @default null
Expand All @@ -168,26 +179,26 @@

/**
* Set the withCredentials flag on the request.
*
*
* @attribute withCredentials
* @type boolean
* @default false
*/
withCredentials: false,

/**
* Additional properties to send to core-xhr.
*
* Can be set to an object containing default properties
* to send as arguments to the `core-xhr.request()` method
* which implements the low-level communication.
*
*
* @property xhrArgs
* @type Object
* @default null
*/
xhrArgs: null,

ready: function() {
this.xhr = document.createElement('core-xhr');
},
Expand All @@ -196,7 +207,7 @@
if (this.isSuccess(xhr)) {
this.processResponse(xhr);
} else {
this.error(xhr);
this.processError(xhr);
}
this.complete(xhr);
},
Expand All @@ -208,12 +219,17 @@

processResponse: function(xhr) {
var response = this.evalResponse(xhr);
this.response = response;
if (xhr === this.activeRequest) {
this.response = response;
}
this.fire('core-response', {response: response, xhr: xhr});
},

error: function(xhr) {
processError: function(xhr) {
var response = xhr.status + ': ' + xhr.responseText;
if (xhr === this.activeRequest) {
this.error = response;
}
this.fire('core-error', {response: response, xhr: xhr});
},

Expand Down Expand Up @@ -277,8 +293,8 @@
this.autoGo();
},

// TODO(sorvell): multiple side-effects could call autoGo
// during one micro-task, use a job to have only one action
// TODO(sorvell): multiple side-effects could call autoGo
// during one micro-task, use a job to have only one action
// occur
autoGo: function() {
if (this.auto) {
Expand Down Expand Up @@ -314,7 +330,10 @@
args.callback = this.receive.bind(this);
args.url = this.url;
args.method = this.method;
return args.url && this.xhr.request(args);

this.response = this.error = null;
this.activeRequest = args.url && this.xhr.request(args);
return this.activeRequest;
}

});
Expand Down

0 comments on commit 509ef7c

Please sign in to comment.