2015-06-05 11:06:36 +02:00
|
|
|
'use strict';
|
|
|
|
|
2015-07-24 13:44:28 +02:00
|
|
|
import Q from 'q';
|
|
|
|
|
2015-07-17 15:41:09 +02:00
|
|
|
import AppConstants from '../constants/application_constants';
|
2015-06-01 14:22:04 +02:00
|
|
|
|
2015-10-30 17:43:20 +01:00
|
|
|
import { getCookie } from '../utils/fetch_api_utils';
|
2015-11-02 18:31:01 +01:00
|
|
|
import { omitFromObject } from '../utils/general_utils';
|
2015-10-30 17:43:20 +01:00
|
|
|
import { argsToQueryParams } from '../utils/url_utils';
|
2015-06-01 14:22:04 +02:00
|
|
|
|
|
|
|
|
2015-06-16 13:48:48 +02:00
|
|
|
class Requests {
|
2015-06-01 14:22:04 +02:00
|
|
|
unpackResponse(response) {
|
|
|
|
if (response.status >= 500) {
|
2015-07-17 16:23:25 +02:00
|
|
|
throw new Error(response.status + ' - ' + response.statusText + ' - on URL:' + response.url);
|
2015-06-01 14:22:04 +02:00
|
|
|
}
|
|
|
|
|
2015-07-24 13:44:28 +02:00
|
|
|
return Q.Promise((resolve, reject) => {
|
2015-07-17 16:44:24 +02:00
|
|
|
response.text()
|
|
|
|
.then((responseText) => {
|
|
|
|
// If the responses' body does not contain any data,
|
|
|
|
// fetch will resolve responseText to the string 'None'.
|
|
|
|
// If this is the case, we can not try to parse it as JSON.
|
|
|
|
if(responseText !== 'None') {
|
|
|
|
let body = JSON.parse(responseText);
|
2015-09-08 11:44:05 +02:00
|
|
|
|
2015-07-17 16:44:24 +02:00
|
|
|
if(body && body.errors) {
|
|
|
|
let error = new Error('Form Error');
|
|
|
|
error.json = body;
|
|
|
|
reject(error);
|
2015-07-17 18:10:11 +02:00
|
|
|
} else if(body && body.detail) {
|
|
|
|
reject(new Error(body.detail));
|
2015-12-08 16:11:27 +01:00
|
|
|
} else if(!body.success) {
|
|
|
|
let error = new Error('Client Request Error');
|
|
|
|
error.json = {
|
|
|
|
status: response.status,
|
|
|
|
statusText: response.statusText,
|
|
|
|
type: response.type,
|
|
|
|
url: response.url
|
|
|
|
};
|
|
|
|
reject(error);
|
2015-07-17 16:44:24 +02:00
|
|
|
} else {
|
|
|
|
resolve(body);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
if(response.status >= 400) {
|
|
|
|
reject(new Error(response.status + ' - ' + response.statusText + ' - on URL:' + response.url));
|
|
|
|
} else {
|
|
|
|
resolve({});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}).catch((err) => {
|
|
|
|
reject(err);
|
|
|
|
});
|
|
|
|
});
|
2015-06-30 17:57:20 +02:00
|
|
|
}
|
|
|
|
|
2015-10-13 16:12:05 +02:00
|
|
|
handleError(url) {
|
|
|
|
return (err) => {
|
|
|
|
if (err instanceof TypeError) {
|
|
|
|
throw new Error('For: ' + url + ' - Server did not respond to the request. (Not even displayed a 500)');
|
|
|
|
} else {
|
|
|
|
throw err;
|
|
|
|
}
|
|
|
|
};
|
2015-06-01 14:22:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
getUrl(url) {
|
2015-07-14 16:29:01 +02:00
|
|
|
// Handle case, that the url string is not defined at all
|
|
|
|
if (!url) {
|
|
|
|
throw new Error('Url was not defined and could therefore not be mapped.');
|
|
|
|
}
|
|
|
|
|
2015-06-01 14:22:04 +02:00
|
|
|
let name = url;
|
|
|
|
if (!url.match(/^http/)) {
|
|
|
|
url = this.urlMap[url];
|
|
|
|
if (!url) {
|
2015-07-17 15:41:09 +02:00
|
|
|
throw new Error(`Cannot find a mapping for "${name}"`);
|
2015-06-01 14:22:04 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return url;
|
|
|
|
}
|
|
|
|
|
2015-06-01 16:45:09 +02:00
|
|
|
prepareUrl(url, params, attachParamsToQuery) {
|
2015-07-14 16:29:01 +02:00
|
|
|
let newUrl;
|
2015-06-01 14:22:04 +02:00
|
|
|
let re = /\${(\w+)}/g;
|
2015-06-02 16:47:25 +02:00
|
|
|
|
2015-07-14 16:29:01 +02:00
|
|
|
// catch errors and throw them to react
|
|
|
|
try {
|
|
|
|
newUrl = this.getUrl(url);
|
|
|
|
} catch(err) {
|
|
|
|
throw err;
|
|
|
|
}
|
2015-08-06 10:09:25 +02:00
|
|
|
|
2015-06-01 14:22:04 +02:00
|
|
|
newUrl = newUrl.replace(re, (match, key) => {
|
2015-06-05 11:06:36 +02:00
|
|
|
let val = params[key];
|
2015-06-01 14:22:04 +02:00
|
|
|
if (!val) {
|
|
|
|
throw new Error(`Cannot find param ${key}`);
|
|
|
|
}
|
|
|
|
delete params[key];
|
|
|
|
return val;
|
|
|
|
});
|
|
|
|
|
2015-06-01 16:45:09 +02:00
|
|
|
if (attachParamsToQuery && params && Object.keys(params).length > 0) {
|
2015-06-02 13:48:01 +02:00
|
|
|
newUrl += argsToQueryParams(params);
|
2015-06-01 14:22:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return newUrl;
|
|
|
|
}
|
|
|
|
|
2015-12-08 16:11:27 +01:00
|
|
|
request(verb, url, options = {}) {
|
2015-11-02 18:27:45 +01:00
|
|
|
let merged = Object.assign({}, this.httpOptions, options);
|
2015-07-16 18:17:45 +02:00
|
|
|
let csrftoken = getCookie(AppConstants.csrftoken);
|
2015-06-16 19:28:21 +02:00
|
|
|
if (csrftoken) {
|
|
|
|
merged.headers['X-CSRFToken'] = csrftoken;
|
|
|
|
}
|
2015-06-05 11:06:36 +02:00
|
|
|
merged.method = verb;
|
2015-06-16 13:48:48 +02:00
|
|
|
return fetch(url, merged)
|
2015-06-01 16:45:09 +02:00
|
|
|
.then(this.unpackResponse)
|
2015-10-13 16:12:05 +02:00
|
|
|
.catch(this.handleError(url));
|
2015-06-01 14:22:04 +02:00
|
|
|
}
|
|
|
|
|
2015-06-01 16:45:09 +02:00
|
|
|
get(url, params) {
|
2015-11-02 18:27:45 +01:00
|
|
|
if (url === undefined) {
|
2015-06-20 16:43:18 +02:00
|
|
|
throw new Error('Url undefined');
|
|
|
|
}
|
2015-11-02 18:27:45 +01:00
|
|
|
let paramsCopy = Object.assign({}, params);
|
2015-06-09 17:24:06 +02:00
|
|
|
let newUrl = this.prepareUrl(url, paramsCopy, true);
|
2015-06-02 14:33:00 +02:00
|
|
|
return this.request('get', newUrl);
|
2015-06-01 14:22:04 +02:00
|
|
|
}
|
|
|
|
|
2015-06-10 15:49:46 +02:00
|
|
|
delete(url, params) {
|
2015-11-02 18:27:45 +01:00
|
|
|
let paramsCopy = Object.assign({}, params);
|
2015-06-10 15:49:46 +02:00
|
|
|
let newUrl = this.prepareUrl(url, paramsCopy, true);
|
|
|
|
return this.request('delete', newUrl);
|
|
|
|
}
|
|
|
|
|
2015-11-02 18:27:45 +01:00
|
|
|
_putOrPost(url, paramsAndBody, method) {
|
2015-11-02 18:31:01 +01:00
|
|
|
let params = omitFromObject(paramsAndBody, ['body']);
|
2015-09-03 15:53:02 +02:00
|
|
|
let newUrl = this.prepareUrl(url, params);
|
2015-12-08 16:11:27 +01:00
|
|
|
let body = paramsAndBody && paramsAndBody.body ? JSON.stringify(paramsAndBody.body)
|
|
|
|
: null;
|
2015-09-03 15:53:02 +02:00
|
|
|
return this.request(method, newUrl, { body });
|
|
|
|
}
|
|
|
|
|
|
|
|
post(url, params) {
|
2015-09-07 16:36:31 +02:00
|
|
|
return this._putOrPost(url, params, 'post');
|
2015-09-03 15:53:02 +02:00
|
|
|
}
|
|
|
|
|
2015-11-02 18:27:45 +01:00
|
|
|
put(url, params) {
|
2015-09-07 16:36:31 +02:00
|
|
|
return this._putOrPost(url, params, 'put');
|
2015-06-01 14:22:04 +02:00
|
|
|
}
|
|
|
|
|
2015-11-02 18:27:45 +01:00
|
|
|
patch(url, params) {
|
2015-09-09 13:53:03 +02:00
|
|
|
return this._putOrPost(url, params, 'patch');
|
|
|
|
}
|
|
|
|
|
2015-06-01 14:22:04 +02:00
|
|
|
defaults(options) {
|
|
|
|
this.httpOptions = options.http || {};
|
|
|
|
this.urlMap = options.urlMap || {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-06-16 13:48:48 +02:00
|
|
|
let requests = new Requests();
|
2015-06-01 14:22:04 +02:00
|
|
|
|
2015-06-16 13:48:48 +02:00
|
|
|
export default requests;
|