Search code examples
javascriptajaxes6-promise

Using promise to call Ajax without duplicating code


is this possible? I want to write an ajax function, that I do not want to duplicate it. Pass it different parameter which are locations to different files. Then use the promise to make them into one object. I would possible use the spread operator. is this possible.

var myFuncCalls = 0;

let promiseAjax = new Promise (function ( resolve,reject) {

//possibly use a for look to grab the number of times the loadDoc was called then call the same function and send it to may be an array?
    function loadDoc(location) {
        myFuncCalls++;
        console.log("loadDoc was called :" + myFuncCalls);



        var xyz = new XMLHttpRequest();
        xyz.onreadystatechange = function () {
            if (this.readyState == 4 && this.status == 200) {
                //console.log(this.responseText)
                resolve(this.responseText);          
            }
        };

        xyz.open("GET", location, true);
        xyz.send();
    }

    loadDoc("/_js/someitems.json");
    loadDoc("/_js/someMoreItems.json");
})

// then grab all that stuff and make one single object using spread operators
promiseAjax.then(function (fromResolve){

    // JSON.parse(fromResolve);
    var newObj = JSON.parse(fromResolve);
    console.log(newObj);

})

Solution

  • with Promise.all and Object.assign,

    function loadDoc(location) {
      return new Promise((resolve, reject) => {
        var xyz = new XMLHttpRequest();
        xyz.onreadystatechange = () => {
          if (this.readyState == 4 && this.status == 200) {
            resolve(JSON.parse(this.responseText));
          } else {
            // resolving with empty object to avoid breaking other fetch if one failed
            resolve({});
          }
        };
    
        xyz.open("GET", location, true);
        xyz.send();
      });
    }
    
    const loadDocs = (paths) => Promise.all(paths.map(path => loadDoc(path))
      .then(results => {
        // combine all result into single object
        return Object.assign({}, ...results);
      }));
    
    // example
    loadDocs([
      "/_js/someitems.json",
      "/_js/someMoreItems.json"
    ]).then(function(finalCombinedObject) {
      // other logic here
    });