chore: make Request and ServerRequest pure JS class
And use UI for dealing with dataloading/dataload events (used for progress bar).
This commit is contained in:
parent
4a99f357f2
commit
0ebb7615aa
2 changed files with 39 additions and 46 deletions
|
@ -1,7 +1,6 @@
|
||||||
// Uses `L._`` from Leaflet.i18n which we cannot import as a module yet
|
// Uses `L._`` from Leaflet.i18n which we cannot import as a module yet
|
||||||
import { Evented, DomUtil } from '../../vendors/leaflet/leaflet-src.esm.js'
|
import { Evented, DomUtil } from '../../vendors/leaflet/leaflet-src.esm.js'
|
||||||
|
|
||||||
|
|
||||||
export class RequestError extends Error {}
|
export class RequestError extends Error {}
|
||||||
|
|
||||||
export class HTTPError extends RequestError {
|
export class HTTPError extends RequestError {
|
||||||
|
@ -20,10 +19,8 @@ export class NOKError extends RequestError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const BaseRequest = Evented.extend({
|
class BaseRequest {
|
||||||
_fetch: async function (method, uri, headers, data) {
|
async _fetch(method, uri, headers, data) {
|
||||||
const id = Math.random()
|
|
||||||
this.fire('dataloading', { id: id })
|
|
||||||
let response
|
let response
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -35,32 +32,29 @@ const BaseRequest = Evented.extend({
|
||||||
})
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
this.fire('dataload', { id: id })
|
|
||||||
throw new HTTPError(error.message)
|
throw new HTTPError(error.message)
|
||||||
}
|
}
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
this.fire('dataload', { id: id })
|
|
||||||
throw new NOKError(response)
|
throw new NOKError(response)
|
||||||
}
|
}
|
||||||
// TODO
|
|
||||||
// - error handling
|
|
||||||
// - UI connection / events
|
|
||||||
|
|
||||||
this.fire('dataload', { id: id })
|
|
||||||
return response
|
return response
|
||||||
},
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
// Basic class to issue request
|
// Basic class to issue request
|
||||||
// It returns a response, or null in case of error
|
// It returns a response, or null in case of error
|
||||||
// In case of error, an alert is sent, but non 20X status are not handled
|
// In case of error, an alert is sent, but non 20X status are not handled
|
||||||
// The consumer must check the response status by hand
|
// The consumer must check the response status by hand
|
||||||
export const Request = BaseRequest.extend({
|
export class Request extends BaseRequest {
|
||||||
initialize: function (ui) {
|
constructor(ui) {
|
||||||
|
super()
|
||||||
this.ui = ui
|
this.ui = ui
|
||||||
},
|
}
|
||||||
|
|
||||||
_fetch: async function (method, uri, headers, data) {
|
async _fetch(method, uri, headers, data) {
|
||||||
|
const id = Math.random()
|
||||||
|
this.ui.fire('dataloading', { id: id })
|
||||||
try {
|
try {
|
||||||
const response = await BaseRequest.prototype._fetch.call(
|
const response = await BaseRequest.prototype._fetch.call(
|
||||||
this,
|
this,
|
||||||
|
@ -73,43 +67,44 @@ export const Request = BaseRequest.extend({
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof NOKError) return this._onNOK(error)
|
if (error instanceof NOKError) return this._onNOK(error)
|
||||||
return this._onError(error)
|
return this._onError(error)
|
||||||
|
} finally {
|
||||||
|
this.ui.fire('dataload', { id: id })
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
get: async function (uri, headers) {
|
async get(uri, headers) {
|
||||||
return await this._fetch('GET', uri, headers)
|
return await this._fetch('GET', uri, headers)
|
||||||
},
|
}
|
||||||
|
|
||||||
post: async function (uri, headers, data) {
|
async post(uri, headers, data) {
|
||||||
return await this._fetch('POST', uri, headers, data)
|
return await this._fetch('POST', uri, headers, data)
|
||||||
},
|
}
|
||||||
|
|
||||||
_onError: function (error) {
|
_onError(error) {
|
||||||
this.ui.alert({ content: L._('Problem in the response'), level: 'error' })
|
this.ui.alert({ content: L._('Problem in the response'), level: 'error' })
|
||||||
},
|
}
|
||||||
|
|
||||||
_onNOK: function (error) {
|
_onNOK(error) {
|
||||||
this._onError(error)
|
this._onError(error)
|
||||||
return error.response
|
return error.response
|
||||||
},
|
}
|
||||||
|
}
|
||||||
})
|
|
||||||
|
|
||||||
// Adds uMap specifics to requests handling
|
// Adds uMap specifics to requests handling
|
||||||
// like logging, CSRF, etc.
|
// like logging, CSRF, etc.
|
||||||
// It expects only json responses.
|
// It expects only json responses.
|
||||||
// Returns an array of three elements: [data, response, error]
|
// Returns an array of three elements: [data, response, error]
|
||||||
// The consumer must check the error to proceed or not with using the data or response
|
// The consumer must check the error to proceed or not with using the data or response
|
||||||
export const ServerRequest = Request.extend({
|
export class ServerRequest extends Request {
|
||||||
_fetch: async function (method, uri, headers, data) {
|
async _fetch(method, uri, headers, data) {
|
||||||
// Add a flag so backend can know we are in ajax and adapt the response
|
// Add a flag so backend can know we are in ajax and adapt the response
|
||||||
// See is_ajax in utils.py
|
// See is_ajax in utils.py
|
||||||
headers = headers || {}
|
headers = headers || {}
|
||||||
headers['X-Requested-With'] = 'XMLHttpRequest'
|
headers['X-Requested-With'] = 'XMLHttpRequest'
|
||||||
return await Request.prototype._fetch.call(this, method, uri, headers, data)
|
return await Request.prototype._fetch.call(this, method, uri, headers, data)
|
||||||
},
|
}
|
||||||
|
|
||||||
post: async function (uri, headers, data) {
|
async post(uri, headers, data) {
|
||||||
const token = document.cookie.replace(
|
const token = document.cookie.replace(
|
||||||
/(?:(?:^|.*;\s*)csrftoken\s*\=\s*([^;]*).*$)|^.*$/,
|
/(?:(?:^|.*;\s*)csrftoken\s*\=\s*([^;]*).*$)|^.*$/,
|
||||||
'$1'
|
'$1'
|
||||||
|
@ -120,14 +115,14 @@ export const ServerRequest = Request.extend({
|
||||||
}
|
}
|
||||||
const response = await Request.prototype.post.call(this, uri, headers, data)
|
const response = await Request.prototype.post.call(this, uri, headers, data)
|
||||||
return await this._as_json(response)
|
return await this._as_json(response)
|
||||||
},
|
}
|
||||||
|
|
||||||
get: async function (uri, headers) {
|
async get(uri, headers) {
|
||||||
const response = await Request.prototype.get.call(this, uri, headers)
|
const response = await Request.prototype.get.call(this, uri, headers)
|
||||||
return await this._as_json(response)
|
return await this._as_json(response)
|
||||||
},
|
}
|
||||||
|
|
||||||
_as_json: async function (response) {
|
async _as_json(response) {
|
||||||
if (Array.isArray(response)) return response
|
if (Array.isArray(response)) return response
|
||||||
try {
|
try {
|
||||||
const data = await response.json()
|
const data = await response.json()
|
||||||
|
@ -142,13 +137,13 @@ export const ServerRequest = Request.extend({
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return this._onError(error)
|
return this._onError(error)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
_onError: function (error) {
|
_onError(error) {
|
||||||
return [{}, null, error]
|
return [{}, null, error]
|
||||||
},
|
}
|
||||||
|
|
||||||
_onNOK: function (error) {
|
_onNOK(error) {
|
||||||
if (error.status === 403) {
|
if (error.status === 403) {
|
||||||
this.ui.alert({
|
this.ui.alert({
|
||||||
content: message || L._('Action not allowed :('),
|
content: message || L._('Action not allowed :('),
|
||||||
|
@ -156,5 +151,5 @@ export const ServerRequest = Request.extend({
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return [{}, error.response, error]
|
return [{}, error.response, error]
|
||||||
},
|
}
|
||||||
})
|
}
|
||||||
|
|
|
@ -98,12 +98,10 @@ L.U.Map.include({
|
||||||
this.urls = new window.umap.URLs(this.options.urls)
|
this.urls = new window.umap.URLs(this.options.urls)
|
||||||
|
|
||||||
this.ui = new L.U.UI(this._container)
|
this.ui = new L.U.UI(this._container)
|
||||||
|
this.ui.on('dataloading', (e) => this.fire('dataloading', e))
|
||||||
|
this.ui.on('dataload', (e) => this.fire('dataload', e))
|
||||||
this.server = new window.umap.ServerRequest(this.ui)
|
this.server = new window.umap.ServerRequest(this.ui)
|
||||||
this.server.on('dataloading', (e) => this.fire('dataloading', e))
|
|
||||||
this.server.on('dataload', (e) => this.fire('dataload', e))
|
|
||||||
this.request = new window.umap.Request(this.ui)
|
this.request = new window.umap.Request(this.ui)
|
||||||
this.request.on('dataloading', (e) => this.fire('dataloading', e))
|
|
||||||
this.request.on('dataload', (e) => this.fire('dataload', e))
|
|
||||||
|
|
||||||
this.initLoader()
|
this.initLoader()
|
||||||
this.name = this.options.name
|
this.name = this.options.name
|
||||||
|
|
Loading…
Reference in a new issue