Een moderne ajax bibliotheek
Home

Titel

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

  1. MDN, Promise
  2. MDN, Oude versie Promise
  3. 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>

JI
2022-05-26 10:12:46