socket_var
socket_var

Reputation: 1093

Promise not resolving as expected

I'm new to the promise world so pls enlighten me on the following scenario:

    function promiseDemo(fetch1,fetch2){
        return Promise.all([fetch1,fetch2]).then(function(values){
        return values[0]+values[1];
        });
    }

   promiseDemo(ajax('sample1.html'),ajax('sample2.html')).then(function(sum){
    console.log(sum);
   },function(){
      console.log('Whoopsie!!!!!'); 
   });


 function ajax(file){
    var httpRequest=new XMLHttpRequest();
    httpRequest.open('GET',file,true);
    httpRequest.onreadystatechange=function(){
    if( httpRequest.readyState == 4){
        if(httpRequest.status == 200){
            console.log('success');
            console.log(httpRequest.responseText);
            return Promise.resolve(httpRequest.responseText);   
        }else{
        console.log('unexpected 400 error');
        return 0;
    }
  }
 }
 httpRequest.send();
 }

The above code takes sample html from two files sample1 and sample2 and appends the text to the dom only when both are retreived.but im gettting values[0] and values[1] as undefined even when reponseText is as expected.What is the problem ??Any suggestion is welcome thank u!!!!

Upvotes: 2

Views: 12466

Answers (3)

hazardous
hazardous

Reputation: 10837

The problem here is that the ajax function returns undefined, instead of a Promise which should be resolved/rejected by the onreadystatuschange function. I think this should work for you...

 function ajax(file){
    return new Promise(function (resolve, reject) {
        var httpRequest=new XMLHttpRequest();

        httpRequest.open('GET', file, true);

        httpRequest.onreadystatechange = function(){
            if(httpRequest.readyState == 4){
                if(httpRequest.status == 200){
                    console.log('success');
                    console.log(httpRequest.responseText);
                    resolve(httpRequest.responseText);   
                }
                else {
                    reject({status: httpRequest.status});
                    return 0;
                }
            }

        }

        httpRequest.send();
    }
}

Upvotes: 1

CodingIntrigue
CodingIntrigue

Reputation: 78525

If you use return anywhere inside the httpRequest.onreadystatechange function, you are not returning a value from ajax but from the onreadystatechange event itself.

In cases where you need to wrap callback code with a Promise, you need to use the Promise constructor:

 function ajax(file) {
     return new Promise((resolve, reject) => {
          var httpRequest = new XMLHttpRequest();
          httpRequest.open('GET', file, true);
          httpRequest.onreadystatechange = function() {
              if (httpRequest.readyState == 4) {
                  if (httpRequest.status == 200) {
                      console.log('success');
                      console.log(httpRequest.responseText);
                      resolve(httpRequest.responseText);
                  } else {
                      console.log('unexpected 400 error');
                      reject(0);
                  }
              }
          }
          httpRequest.send();
     });
 }

Just for reference, there is a new method called fetch which already achieves what you are looking for. You can use it as:

promiseDemo(fetch('sample1.html'),fetch('sample2.html')).then(function(sum){
    console.log(sum);
   },function(){
      console.log('Whoopsie!!!!!'); 
   });

A polyfill for browsers is available on GitHub.

Upvotes: 5

Daan Reid
Daan Reid

Reputation: 361

I believe your ajax function does not return a promise, so the promiseDemo is not getting any promise values to resolve. Try checking what gets passed into the promiseDemo function.

If that's the problem, you can fix it by creating a new promise in the ajax function that is returned immediately, and resolved in the http request callback function.

Upvotes: 0

Related Questions