Een moderne ajax bibliotheek
We hebben al een Ajax klasse gemaakt in een Ajax bibliotheek. De bibliotheek volstond voor één enkele ajax call tegelijk maar voldeed niet voor geneste ajax call's. Dat gaan we nu verbeteren door gebruik te maken van promises. Daarnaast gaan we de GET, PUT, POST en DELETE volgends het adapter pattern implementeren.
Bron
- MDN, Promise
- MDN, Oude versie Promise
- Jake Archibald, JavaScript Promises: an Introduction, 16 december 2016
Inleiding
Met de moderne versie van de Ajax bibliotheek willen we verschillende ajax call's kunnen nesten zodat de tweede call niet wordt uitgevoerd vooraleer de eerste is afgewerkt. Dit is nodig wanneer het resultaat van de eerste call door de tweede gebruikt wordt.
Code
De code vanop MDN is lichtjes aangepast zodat we opeenvolgende then's kunnen chainen.
Er is niets mysterieus aan het gebruik van $ in JavaScript. $ Is gewoon een geldige JavaScript identifier. Identifiers in JavaScript kunnen hoofd- en kleine letters, cijfers en _ en $ bevatten.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Adapter pattern</title>
<script>
function $http(url) {
// A small example of object
let core = {
// Method that performs the ajax request
ajax: function (method, url, args) {
// Creating a promise
let promise = new Promise(function (resolve, reject) {
// Instantiates the XMLHttpRequest
let client = new XMLHttpRequest();
let uri = url;
// payload to string
let payload = '';
let argcount = 0;
for (let key in args) {
if (args.hasOwnProperty(key)) {
if (argcount++) {
payload += '&';
}
payload += encodeURIComponent(key) + '=' + encodeURIComponent(args[key]);
}
}
if (method === 'GET') {
if (payload) {
uri += '?';
}
}
client.open(method, uri, true);
if (method === 'POST') {
//Send the proper header information along with the request
// request must be opened
client.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
}
client.send(payload);
client.onload = function () {
if (this.status == 200) {
// Performs the function 'resolve' when this.status is equal to 200
resolve(this.response);
}
else {
// Performs the function 'reject' when this.status is different than 200
// je toont alleen de this.responseText in de ontwikkelingsfase
// niet in de productiefase
reject(this.statusText + this.responseText);
}
};
client.onerror = function () {
reject(this.statusText);
};
});
// Return the promise
return promise;
}
};
// Adapter pattern
return {
'get': function (args) {
return core.ajax('GET', url, args);
},
'post': function (args) {
return core.ajax('POST', url, args);
},
'put': function (args) {
return core.ajax('PUT', url, args);
},
'delete': function (args) {
return core.ajax('DELETE', url, args);
}
};
};
// End A
// B-> Here you define its functions and its payload
var payload = {
'topic': 'js',
'q': 'Promise'
};
var callback = {
success: function (data) {
var pre = document.createElement('PRE');
var t = document.createTextNode(data);
pre.appendChild(t);
document.body.appendChild(pre);
},
error: function (data) {
var pre = document.createElement('PRE');
var t = document.createTextNode('<b>' + 2 + '</b> error ' + data);
pre.appendChild(t);
document.body.appendChild(pre);
}
};
// End B
window.onload = function () {
// Executes the method call
$http('data/procedureList.json')
.get(payload)
.then(function (data) {
callback.success(data);
return $http('data/organisationList.json').get(payload);
})
.catch(callback.error)
.then(function (data) {
callback.success(data);
})
.catch(callback.error);
}
</script>
</head>
<body>
</body>
</html>
2022-05-26 10:12:46