简体   繁体   中英

Weird error with promise and ember

I have following function, which returns promise for authentication

authenticate: function(options) {
    return new Promise((resolve, reject) => {
      $.ajax({
        url: this.tokenEndpoint,
        type: 'POST',
        headers: {'Content-Type': 'application/json', 'Accept-Encoding': 'gzip, deflate'},
        data: JSON.stringify({
          username: options.identification,
          password: options.password
        })
      }).then(function(response) {
            console.log(response) // I get here object with good properties 
            resolve({
                lastLoginDate: response.lastLoginDate,
                login: response.login,
                name: response.name,
                role: response.role,
                token: response.id_token
              });
          }, function(xhr, status, error) {
            if(error !== undefined) {
              console.log(error);
            }

            var response = xhr.responseText;
              reject(response);
          });
    });

When i call it and pass good username and password it returns "undefined", but when i pass bad properties, my "reject" works perfectly . Does someone know why my "then" doesn't return expected output?

  this.get('session').authenticate('authenticator:custom', {'identification': identification, 'password': password})
    .then((data)=>{
      console.log(data); //Undefined <- here is my problem.
    })
    .catch((reason) => {
      console.log(reason); // It works, when pass bad password!
      this.set('errorMessage', reason.error);
    });

Firstly, $.ajax returns a jQuery Promise which these days is 99.999% as good as a native Promise - so no need to wrap $.ajax in a Promise

Secondly, .then takes two callback arguments, onfullfilled and onrejected, both of these callbacks only receive a single argument - your onrejected callback will never have status and error arguments - so that code is flawed

In the onfullfilled callback, the argument is an array, being the [result, status, jqXHR] that you would get in the $.ajax success call

Similarly, in the onrejected callback, the argument is an array, being [jqXHR, status, errorThrown]

Given all that, the authenticate function can be written

authenticate: function(options) {
    return $.ajax({
        url: this.tokenEndpoint,
        type: 'POST',
        headers: {'Content-Type': 'application/json', 'Accept-Encoding': 'gzip, deflate'},
        data: JSON.stringify({
          username: options.identification,
          password: options.password
        })
    })
    .then(function(arr) {
            var response = arr[0];
            console.log(response);
            // return instead of resolve
            return({
                lastLoginDate: response.lastLoginDate,
                login: response.login,
                name: response.name,
                role: response.role,
                token: response.id_token
            });
        }, function(arr) {
            var xhr = arr[0], status = arr[1], error = arr[2];

            if(error !== undefined) {
                console.log(error);
            }
            var response = xhr.responseText;
            // return a rejection - could "throw response" instead
            return Promise.reject(response);
        }
    );
}

and FYI - ES2015+ you could write

.then(function([response, status, xhr]) {
.....
}, function([xhr, status, error]) {
....

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM