Files
2025-08-27 07:03:09 +00:00

129 lines
5.2 KiB
JavaScript
Executable File

/**
* Base model class
*
* @author Nicolas Stein
* @author Michael Fallise
* @version 1.2
* @category Core
* @subcategory Application
*/
class Model {
/**
*
* @param {object} response
* @returns {object}
*/
_processResponse(response, resolve, reject){
if(response.ok){ // All ok
if( (response.headers.get('Content-Type')) && (response.headers.get('Content-Type').toLocaleLowerCase().indexOf('application/json')>-1) ) {
resolve(response.json());
} else {
resolve(
response.text().then(rawResponse => {
if(rawResponse != '') {
console.warn('Server did not declare response as Json...trying to parse it anyway', rawResponse)
return(JSON.parse(rawResponse));
} else if(response.status==204) return(true); // Normal to have no content, so make sure other layers see it as success
else return('');
})
)
}
} else { // server error
// server error with json error details
if( (response.headers.get('Content-Type')) && (response.headers.get('Content-Type').toLocaleLowerCase().indexOf('application/json')>-1) ){
response.json().then(
cleanJson => { // json error details is clean
let error = {
'code': response.status,
'displayMessage': (cleanJson.error.displayMessage || ' !!No debugMessage from server!!'),
'debugMessage': response.statusText+'\n'+(cleanJson.error.debugMessage || ' !!No debugMessage from server!!'),
}
this.onRequestError(error);
reject(error);
},
text => {
let error = { // json error details is garbage
'code': response.status,
'displayMessage': 'Could not request to server!?',
'debugMessage': 'Additionally, bad Json returned :', text,
}
this.onRequestError(error);
reject(error);
}
)
} else { // server error with text return
response.text().then(
text => {
let error = {
'code': response.status,
'displayMessage': 'Could not request to server!?',
'debugMessage': `Server responded: ${text}`,
}
this.onRequestError(error);
reject(error);
},
)
}
}
}
/**
* Generic API service call
* @param {string} uri
* @param {string} method
* @param {object} payload
* @returns {object}
*/
request(uri, method, payload) {
// Fetch chooses its own resolve/reject (see https://developer.mozilla.org/en-US/docs/Web/API/fetch)
// Errors like 404 are not rejected. and we can't change the -already done- resolve/reject choice.
// therefore we return our own promise.
if((!method) || (!uri)) {
return(
new Promise((resolve, reject) => reject(
{ sucess :false,
payload: null,
error: { displayError: 'Server Error (no endpoint)',
debugError: 'Missing endpoint' },
})
))
}
return (
new Promise((resolve, reject) => {
let body = null;
if(method.toLowerCase()!='get') body = payload ? JSON.stringify(payload): null;
else if(payload) uri += '?'+Object.entries(payload).map(kv => kv.map(encodeURIComponent).join("=")).join("&");
fetch(uri, {
method: method,
headers: { 'Accept': 'application/json', 'Content-Type':'application/json'},
body: body,
credentials: 'include', //By nike: mandatory for MT to get session !!!
})
.then( response => {
this._processResponse(response, resolve, reject);
})
.catch(debugMessage => { // Other errors like metwork, protocol, CORs errors, or 200 but bad JSON
let error = {
'displayMessage': 'Could not request to server!?',
'debugMessage': debugMessage,
'code': '4XX' // non http but >299
}
this.onRequestError(error);
reject(error);
})
})
);
}
/**
* Request error handler
* @param {object} error
*/
onRequestError(error) { console.error('Ajax request error:', error); }
}
app.registerClass('Model', Model)