HTML/JS: How we Send and Receive JSON data from APL Server
1 post
• Page 1 of 1
HTML/JS: How we Send and Receive JSON data from APL Server
Here are the functions that we are using to Send and Receive JSON data from an APL server:
To send JSON data:
To request some JSON data from an APL server:
Comments and suggestions for improvements are welcome.
To send JSON data:
- Code: Select all
function sendJSON(jsObject) {
// From: https://developers.google.com/web/updates/2015/03/introduction-to-fetch
// https://developers.google.com/web/updates/2017/09/abortable-fetch
// https://developers.google.com/web/ilt/pwa/working-with-the-fetch-api
// Function to send data to APL without any data in return.
// With POST it is permitted to send JSON data in the 'body' property.
// Usage:
//sendJSON(r)
// .then(() => ) // success
// .catch(() => ) // failure
// .finally(() => ) // always
// Convert the Javascript Object(jsObject) to a JSON Object (jsonObject).
let jsonString;
try {
if (isString(jsObject)) {
// If the string will make an error when parsed by Apl,
// it will return a statusCode of 400 for bad request.
jsonString = jsObject;
} else {
// The following line will always work because a faulty object argument will
// make a syntax error before calling sendJSON.
jsonString = JSON.stringify(jsObject);
}
} catch (error) {
//console.error(`getJSON: Ill formed request:\nRequest: ${jsObject}\nError: ${error.message}`);
//return Promise.reject(new Error(`sendJSON: Ill formed request:\nRequest: ${jsonString}\nError: ${error.message}`));
// The following line should never be called because there no error that will go to here.
// Erase if it is the case.
let catchError = `{"name":"Parsing Error","responseText":"Error parsing ${jsObject}","sender":"getJSON","statusCode":0,"statusText":"${error.message}"}`;
return new Error(catchError);
}
// Prepare an AbortController that will time-out if no response from Apl.
// There is no time-out option in fetch, has to be made with code.
let timeOut;
if ('TimeOut' in jsObject) {
timeOut = jsObject.TimeOut;
} else {
timeOut = 750; // default 0.75 second time-out
}
const controller = new AbortController();
setTimeout(() => {
controller.abort()
}, timeOut);
// Make the call using javascript 'fetch'.
return fetch(_URL, {
method: 'POST',
body: jsonString,
signal: controller.signal
}).then((response) => {
// if (response.status >= 200 && response.status < 300) { // same as line below.
if (response.ok) {
return Promise.resolve(response)
} else {
//return Promise.reject(new Error(response.statusText))
return response.text().then(text => {
return Promise.reject({
name: "notAbortError",
responseText: text,
sender: "?", // to be completed
statusCode: response.status,
statusText: response.statusText
});
});
}
}).catch((error) => {
// When the AbortController time-out it will create an Error with name 'AbortError'.
// Otherwise it will read the error made in the above Promise.reject.
// The constructor of Error only accept characters and not an object to be passed.
// Those characters can be read back with the property .message of the Error object.
if (error.name === 'AbortError') {
// The AbortController has time-out and throw the 'AbortError'.
// Next line does not work without 'throw'.
throw new Error('{"name":"AbortError","responseText":"No Response From Server","sender":"?","statusCode":408,"statusText":"Request Timeout"}')
} else {
// Error from the above Promise.reject.
throw new Error(JSON.stringify(error))
}
})
}
To request some JSON data from an APL server:
- Code: Select all
function getJSON(jsObject) {
// Function to get data from APL server.
// With GET it is not permitted to send JSON data in the 'body' property.
// Usage:
// getJSON(r)
// .then(() => ) // success
// .catch(() => ) // failure
// .finally(() => ) // always
// https://codereview.stackexchange.com/questions/173538/timeout-implementation-of-fetch (don't understand)
// https://www.lowmess.com/blog/fetch-with-timeout/ (working)
// Convert the Javascript Object(jsObject) to a JSON Object (jsonObject).
let jsonString;
try {
if (isString(jsObject)) {
// If the string will make an error when parsed by Apl,
// it will return a statusCode of 400 for bad request.
jsonString = jsObject;
} else {
// The following line will always work because a faulty object argument will
// make a syntax error before calling getJSON.
jsonString = JSON.stringify(jsObject);
}
} catch (error) {
//console.error(`getJSON: Ill formed request:\nRequest: ${jsObject}\nError: ${error.message}`);
//return Promise.reject(new Error(`getJSON: Ill formed request:\nRequest: ${jsonString}\nError: ${error.message}`));
// The following line should never be called because there no error that will go to here.
// Erase if it is the case.
let catchError = `{"name":"Parsing Error","responseText":"Error parsing ${jsObject}","sender":"getJSON","statusCode":0,"statusText":"${error.message}"}`;
return new Error(catchError);
}
let url = _URL + "&request=" + encodeURIComponent(jsonString);
// Prepare an AbortController that will time-out if no response from Apl.
// There is no time-out option in fetch, has to be made with code.
let timeOut;
if ('TimeOut' in jsObject) {
timeOut = jsObject.TimeOut;
} else {
timeOut = 750; // default 0.75 second time-out
}
const controller = new AbortController();
setTimeout(() => {
controller.abort()
}, timeOut);
// Fetch call is made here.
return fetch(url, {
method: 'GET',
signal: controller.signal
}).then((response) => {
// if (response.status >= 200 && response.status < 300) { // same as line below.
if (response.ok) {
return Promise.resolve(response.json()) // JSON.Parse the answer.
} else {
//return Promise.reject(new Error(response.statusText)) // ←←← not possible to get Apl error with this code
// response.text will get us the error sent from Apl.
return response.text().then((text) => { // no parsing.
return Promise.reject({
name: "notAbortError",
responseText: text,
sender: "?", // to be completed
statusCode: response.status,
statusText: response.statusText
});
});
}
})
.catch((error) => {
// When the AbortController time-out it will create an Error with name 'AbortError'.
// Otherwise it will read the error made in the above Promise.reject.
// The constructor of Error only accept characters and not an object to be passed.
// Those characters can be read back with the property .message of the Error object.
if (error.name === 'AbortError') {
// The AbortController has time-out and throw the 'AbortError'.
// Next line does not work without 'throw'.
throw new Error('{"name":"AbortError","responseText":"No Response From Server","sender":"?","statusCode":408,"statusText":"Request Timeout"}')
} else {
// Error from the above Promise.reject.
throw new Error(JSON.stringify(error))
}
})
Comments and suggestions for improvements are welcome.
-
PGilbert - Posts: 436
- Joined: Sun Dec 13, 2009 8:46 pm
- Location: Montréal, Québec, Canada
1 post
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 1 guest
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group