Browse Source

Refactor RemoteStorage

pull/4223/head
Artur Arseniev 5 years ago
parent
commit
076a1915fd
  1. 9
      src/storage_manager/config/config.js
  2. 167
      src/storage_manager/model/RemoteStorage.js

9
src/storage_manager/config/config.js

@ -25,9 +25,6 @@ export default {
checkLocal: true, checkLocal: true,
}, },
remote: { remote: {
// Custom parameters to pass with the remote request, eg. csrf token
params: {},
// Custom headers // Custom headers
headers: {}, headers: {},
@ -37,12 +34,6 @@ export default {
// Endpoint URL where to load data project // Endpoint URL where to load data project
urlLoad: '', urlLoad: '',
//Callback before request
beforeSend(jqXHR, settings) {},
//Callback after request
onComplete(jqXHR, status) {},
// set contentType paramater of $.ajax // set contentType paramater of $.ajax
// true: application/json; charset=utf-8' // true: application/json; charset=utf-8'
// false: 'x-www-form-urlencoded' // false: 'x-www-form-urlencoded'

167
src/storage_manager/model/RemoteStorage.js

@ -1,146 +1,67 @@
import Backbone from 'backbone';
import fetch from 'utils/fetch'; import fetch from 'utils/fetch';
import { isUndefined, isFunction } from 'underscore'; import { Model } from 'common';
import { isUndefined, isFunction, isString } from 'underscore';
export default Backbone.Model.extend({ export default class RemoteStorage extends Model {
fetch, async store(data, opts = {}) {
await this.request(opts.urlStore, this.__props(opts, data), opts);
defaults: { }
urlStore: '',
urlLoad: '',
params: {},
beforeSend() {},
onComplete() {},
contentTypeJson: false,
credentials: 'include',
fetchOptions: ''
},
/**
* Triggered before the request is started
* @private
*/
onStart() {
const em = this.get('em');
const before = this.get('beforeSend');
before && before();
},
/**
* Triggered on request error
* @param {Object} err Error
* @param {Function} [clbErr] Error callback
* @private
*/
onError(err, clbErr) {
if (clbErr) {
clbErr(err);
} else {
const em = this.get('em');
console.error(err);
em && em.trigger('storage:error', err);
}
},
/**
* Triggered on request response
* @param {string} text Response text
* @private
*/
onResponse(text, clb) {
const em = this.get('em');
const complete = this.get('onComplete');
const typeJson = this.get('contentTypeJson');
const parsable = text && typeof text === 'string';
const res = typeJson && parsable ? JSON.parse(text) : text;
complete && complete(res);
clb && clb(res);
em && em.trigger('storage:response', res);
},
store(data, clb, clbErr) {
const body = {};
for (let key in data) {
body[key] = data[key];
}
this.request(this.get('urlStore'), { body }, clb, clbErr); async load(opts) {
}, return await this.request(opts.urlLoad, this.__props(opts), opts);
}
load(keys, clb, clbErr) { request(url, props = {}, opts = {}) {
this.request(this.get('urlLoad'), { method: 'get' }, clb, clbErr); return fetch(url, props)
}, .then(res => {
const result = res.text();
const isOk = ((res.status / 200) | 0) === 1;
return isOk ? result : result.then(Promise.reject);
})
.then(text => {
const parsable = text && isString(text);
return opts.contentTypeJson && parsable ? JSON.parse(text) : text;
});
}
/** __props(opts = {}, data) {
* Execute remote request const typeJson = opts.contentTypeJson;
* @param {string} url Url const headers = opts.headers || {};
* @param {Object} [opts={}] Options const fetchOpts = opts.fetchOptions || {};
* @param {Function} [clb=null] Callback
* @param {Function} [clbErr=null] Error callback
* @private
*/
request(url, opts = {}, clb = null, clbErr = null) {
const typeJson = this.get('contentTypeJson');
const headers = this.get('headers') || {};
const params = this.get('params');
const reqHead = 'X-Requested-With'; const reqHead = 'X-Requested-With';
const typeHead = 'Content-Type'; const typeHead = 'Content-Type';
const bodyObj = opts.body || {};
let fetchOptions;
let body; let body;
for (let param in params) {
bodyObj[param] = params[param];
}
if (isUndefined(headers[reqHead])) { if (isUndefined(headers[reqHead])) {
headers[reqHead] = 'XMLHttpRequest'; headers[reqHead] = 'XMLHttpRequest';
} }
// With `fetch`, have to send FormData without any 'Content-Type'
// https://stackoverflow.com/questions/39280438/fetch-missing-boundary-in-multipart-form-data-post
if (isUndefined(headers[typeHead]) && typeJson) { if (isUndefined(headers[typeHead]) && typeJson) {
headers[typeHead] = 'application/json; charset=utf-8'; headers[typeHead] = 'application/json; charset=utf-8';
} }
if (typeJson) { if (data) {
body = JSON.stringify(bodyObj); if (typeJson) {
} else { body = JSON.stringify(data);
body = new FormData(); } else {
body = new FormData();
for (let bodyKey in bodyObj) { for (let key in data) {
body.append(bodyKey, bodyObj[bodyKey]); body.append(key, data[key]);
}
} }
} }
fetchOptions = {
method: opts.method || 'post',
credentials: this.get('credentials'),
headers
};
// Body should only be included on POST method const result = {
if (fetchOptions.method === 'post') { method: body ? 'post' : 'get',
fetchOptions.body = body; credentials: opts.credentials,
} headers,
body,
const fetchOpts = this.get('fetchOptions') || {}; };
const addOpts = isFunction(fetchOpts)
? fetchOpts(fetchOptions)
: fetchOptions;
this.onStart(); return {
this.fetch(url, { ...result,
...fetchOptions, ...(isFunction(fetchOpts) ? fetchOpts(result) : fetchOpts),
...(addOpts || {}) };
})
.then(res =>
((res.status / 200) | 0) == 1
? res.text()
: res.text().then(text => Promise.reject(text))
)
.then(text => this.onResponse(text, clb))
.catch(err => this.onError(err, clbErr));
} }
}); }

Loading…
Cancel
Save