Skip to content

Commit

Permalink
Add middleware, add new examples, fix readme, bump version to 1.1.2
Browse files Browse the repository at this point in the history
  • Loading branch information
Zlobin committed May 17, 2016
1 parent adca13a commit 18e91e9
Show file tree
Hide file tree
Showing 9 changed files with 141 additions and 40 deletions.
59 changes: 36 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ Dependencies: [object-hash](https://www.npmjs.com/package/object-hash), [qs](htt

## Installation

`npm i --save es-ajax`
or
`git clone https://github.com/Zlobin/es-ajax.git`
`cd es-ajax && npm i && webpack`
`npm i --save es-ajax`<br>
or<br>
`git clone https://github.com/Zlobin/es-ajax.git`<br>
`cd es-ajax && npm i && webpack`<br>

## Examples

Expand Down Expand Up @@ -102,8 +102,9 @@ ajax('/some/url', {
});
```
:TODO
Middleware is the programming pattern of providing hooks with a resume callback. It will be calling before a request was sent. It is able to cancel request, change URL and headers before sending. May be used, for instance, when you want to use some cache library, allow only some http-methods, like GET and POST, for instance. Some examples:
Middleware is the programming pattern of providing hooks with a resume callback. It will be calling before a request was sent. It is able to cancel request, change URL and headers before sending. May be used, for instance, when you want to use some cache library, allow only some http-methods, like GET and POST, for instance.
Some examples:
```js
var cache = function(next) {
var response = null;
Expand All @@ -117,16 +118,21 @@ var cache = function(next) {
});
if (response !== null) {
console.log('Data from cache.');
console.log('Data from a cache.');
// Do not send request to the server.
// Return cached response.
// @todo
return new Promise(function(resolse, reject) {
resolse({
response: response,
headers: []
});
});
} else {
console.log('Send request to the server.');
next();
return next();
}
} else {
next();
return next();
}
};
Expand All @@ -139,7 +145,13 @@ ajax('/foo/bar')
.then(function() {
// Second one - not. We will get data immediately from a cache.
ajax('/foo/bar')
.get();
.get()
.then(function() {
// ...
})
.catch(function() {
// ...
});
})
.catch(function() {
// ...
Expand All @@ -149,13 +161,14 @@ ajax('/foo/bar')
Or if you want to allow to use only GET requests:
```js
var onlyGet = function(request, next) {
if (request.method === 'GET') {
next();
}
throw new Error('Allows only GET methods');
// ...
var onlyGet = function(next) {
return this.request.method === 'GET' ?
next() : new Promise(function(resolse, reject) {
reject({
response: 'Only "GET" methods is available.',
headers: []
});
});
};
ajax()
Expand All @@ -171,7 +184,7 @@ ajax('/foo/bar')
});
ajax('/foo/bar')
.get()
.post()
.then(function() {
// ...
})
Expand Down Expand Up @@ -212,7 +225,7 @@ You can grab minified versions of es-ajax from /dist path after running `webpack
## TODO
1. Middleware
2. Send more than one file
3. Add more tests
4. Singleton request
1. Send more than one file
2. Add more tests
3. Singleton request
4. Add custom parameters to the demo
28 changes: 27 additions & 1 deletion demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ <h3 class="panel-title">Response</h3>
var addHeader = byId('add-header');
var headers = byId('headers');
var progressBar = byId('progressbar');
var applyMiddleware = byId('apply-middleware');
var clearMiddleware = byId('clear-middleware');
var activeRequest = null;
// For checking json object as parameters
// with nested objects and arrays.
Expand All @@ -145,7 +147,10 @@ <h3 class="panel-title">Response</h3>
]
};
var responseOut = function(response) {
response.response = JSON.parse(response.response);
try {
response.response = JSON.parse(response.response);
} catch (e) {}

return JSON.stringify(response, undefined, 2);
};
var setProgress = function(percentage) {
Expand Down Expand Up @@ -187,6 +192,19 @@ <h3 class="panel-title">Response</h3>

return customHeaders;
};
var middleware = function(next) {
var requests = this.getRequests();

return requests.method === 'GET' ?
next() :
new Promise(function(resolve, reject) {
reject({
status: 0,
response: 'Only "GET" requests',
headers: []
});
});
};

send.addEventListener('click', function(event) {
var url = prepareUrl('url');
Expand Down Expand Up @@ -275,6 +293,14 @@ <h3 class="panel-title">Response</h3>
fileBlock.style.display = (method.value === 'file'
? 'block' : 'hidden');
});

applyMiddleware.addEventListener('click', function() {
ajax().use(middleware);
});

clearMiddleware.addEventListener('click', function() {
location.reload();
});
})(document, ajax);
</script>
</body>
Expand Down
2 changes: 0 additions & 2 deletions links

This file was deleted.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "es-ajax",
"description": "Ajax (fetch or xhr2) with promises - an useful JavaScript library for convenient work with ajax requests in a browser.",
"version": "1.1.1",
"version": "1.1.2",
"main": "src/index.js",
"files": [
"src",
Expand Down Expand Up @@ -38,7 +38,7 @@
],
"license": "MIT",
"dependencies": {
"es-middleware": "^1.0.2",
"es-middleware": "^1.1.0",
"object-hash": "^1.1.2",
"qs": "^6.1.0"
},
Expand Down
2 changes: 1 addition & 1 deletion src/ajax.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export function ajax(url, parameters = {}) {
if (!xhrApi && url) {
// Create new instance.
xhrApi = factory(settings.api, url, settings.request, settings.headers);
xhrApi.setMiddlewareRun(mw.run);
xhrApi.setMiddleware(mw);
xhrApi.onBeforeSend(params => {
const { headers, request, time } = params;
const hash = objectHash({
Expand Down
18 changes: 18 additions & 0 deletions src/api/fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ export default class FetchAPI extends XhrAbstract {
throw new Error('Currently it is not possible to set timeout for "fetch".');
}

getHeaders() {
return internal(this)._headers;
}

hasHeader(header) {
return internal(this)._headers.has(header);
}
Expand All @@ -71,6 +75,10 @@ export default class FetchAPI extends XhrAbstract {
return this;
}

getRequests() {
return internal(this)._requests;
}

setRequest(request = {}) {
// const self = internal(this);

Expand All @@ -85,4 +93,14 @@ export default class FetchAPI extends XhrAbstract {

return this;
}

setUrl(url) {
internal(this)._url = url;

return this;
}

getUrl() {
return internal(this)._url;
}
}
34 changes: 27 additions & 7 deletions src/api/xhr-abstract.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ import { is } from '../utils/is';

export default class XhrAbstract {
constructor(/* url, request = {}, headers = {} */) {
if (is._undefined(this.middleware)) {
this.middleware = {};
this.middleware = {
run: () => {},
setContext: () => {}
};
}

return this;
}

Expand Down Expand Up @@ -110,12 +118,8 @@ export default class XhrAbstract {
return this.send();
}

setMiddlewareRun(middleware) {
if (!is._function(middleware)) {
throw new TypeError('Parameter must be a function.');
}

this.run = middleware;
setMiddleware(middleware) {
this.middleware = middleware;
}

send() {
Expand All @@ -130,6 +134,10 @@ export default class XhrAbstract {
//
}

getHeaders() {
//
}

hasHeader(/* header */) {
//
}
Expand All @@ -138,6 +146,10 @@ export default class XhrAbstract {
//
}

getRequests() {
//
}

setRequest(/* request */) {
//
}
Expand All @@ -147,6 +159,14 @@ export default class XhrAbstract {
}

onBeforeSend(/* callback */) {
// ...
//
}

getUrl() {
//
}

setUrl(/* url */) {
//
}
}
30 changes: 28 additions & 2 deletions src/api/xhr.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ export default class XhrAPI extends XhrAbstract {
internal(this)._timeout = timeout;
}

send(isFile = false) {
// @todo wrap around this.run
sendRequest() {
const self = internal(this);
const xhr = self._xhr;
const isFile = self._isFile;
const { method, async, body } = self._requests;
// Split an object into query-string like ?foo=bar&bar=baz
const data = is._object(body) && !isFile ? qs.stringify(body) : body;
Expand Down Expand Up @@ -156,6 +156,14 @@ export default class XhrAPI extends XhrAbstract {
});
}

send(isFile = false) {
internal(this)._isFile = isFile;

return this.middleware
.setContext(this)
.run(this.sendRequest.bind(this));
}

cancel() {
const xhr = internal(this)._xhr;

Expand All @@ -177,6 +185,10 @@ export default class XhrAPI extends XhrAbstract {
return this;
}

getHeaders() {
return internal(this)._headers;
}

hasHeader(header) {
return !!internal(this)._xhr.getResponseHeader(header);
}
Expand All @@ -197,6 +209,10 @@ export default class XhrAPI extends XhrAbstract {
return this;
}

getRequests() {
return internal(this)._requests;
}

setRequest(request = {}) {
const self = internal(this);

Expand All @@ -212,4 +228,14 @@ export default class XhrAPI extends XhrAbstract {

return this;
}

setUrl(url) {
internal(this)._url = url;

return this;
}

getUrl() {
return internal(this)._url;
}
}
4 changes: 2 additions & 2 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function prepareRespond(url, method = 'GET') {

function respond() {
fakeServer.respond();
console.log('fakeServer', fakeServer.requests[fakeServer.requests.length - 1].requestHeaders);
// console.log('fakeServer', fakeServer.requests[fakeServer.requests.length - 1].requestHeaders);
fakeServer.restore();
}

Expand Down Expand Up @@ -58,7 +58,7 @@ describe('1. es-ajax test', () => {
'getAllRequests',
'setOverride',
'setTimeout',
'applyMiddleware'
'use'
].forEach(method =>
it(`1.1.${++i}: should have "${method}" method`, () =>
expect(ajax(URL)[method]).toBeA('function'))
Expand Down

0 comments on commit 18e91e9

Please sign in to comment.