byrdr
byrdr

Reputation: 5477

Angular $q returning resolved promise

I have a variable this.eligible which I would like to assign to the value of a returned promise instead of the actual promise object.

userService

this.eligible = this.sweepstakesService.checkUser(data);

sweepstakesService

checkUser({profileId}) {
var deferred = this.$q.defer();
var id = profileId.replace(/[{}]/g, "");

this.$q.when(this.getGuid(id)
  .then(guid => this.determineEligibility(guid))
  .catch(this.handleError))
  .then(function(data){
      deferred.resolve(data);
});

  return deferred.promise;

}

 getGuid(profileId){
    return this.resourcesService.guid.save({id:profileId}).$promise.then(data => data.guid);
  }

 determineEligibility(response){
      return this.resourcesService.eligibility.save({id:response}).$promise.then(data => data.isEligible);
    }


 handleError(response){
      console.log(response);
  }

Currently I'm returning Promise{$$state: Object} instead of the actual resolved value.

Upvotes: 2

Views: 3640

Answers (2)

Paul Boutes
Paul Boutes

Reputation: 3315

When you're using promise, you're performing some asynchronous request, so you have to pass some callback function in order to retrieve your data, and wait for it.

You can use the $q.defer() promise manager, from the deferred API.

$q.defer() get 2 methods :

  • resolve(value) : which resolve our associated promise, by giving her the final value

  • reject(reason) : which resolve an promise error.

Don't forget that you are doing some asynchronous work...

Moreover, a good tips can be to save the current context into a variable, in order to bind your data.

Controller

(function(){

function Controller($scope, Service) {

  //Save the current context of our controller
  var self = this;

  self.success = '';

  self.fail = '';

  //Declare our promise
  var promise1 = Service.get(2);

  var promise2 = Service.get(6);

  promise1.then(function(response){
    //Retrieve our response and set it to our success variable
    //We use self as our Controller context
    self.success = response;
  }).catch(function(error){
    self.success = error;
  });

  promise2.then(function(response){
    self.fail = response;
  }).catch(function(error){
    //Retrieve our error and set it to our fail variable
    self.fail = error;
  });


}

angular
.module('app', [])
.controller('ctrl', Controller);

})();

Service

(function(){

  function Service($http, $q) {

    function get(n){
      //using $q.defer() from deferred API
      var defer = $q.defer();

      //Simulate latency
      setTimeout(function(){
        n < 3
        ? defer.resolve(n)
        : defer.reject('Error');
      }, 1500);

      //Return our promise
      return defer.promise;

    }

    return {
      get: get
    }

  }

  angular
    .module('app')
    .factory('Service', Service);

})();

Then, you can instantiate your controller by using the controllerAs syntax.

HTML

  <body ng-app='app' ng-controller='ctrl as self'>

    <div>Success : {{self.success}}</div>
    <div>Fail : {{self.fail}}</div>

  </body>

You can see an example on this Working Plunker

Upvotes: 0

Claies
Claies

Reputation: 22323

In order to access the result of a promise, you need to provide a callback to the then method on the promise object, which will be called asynchronously as soon as the result is available.

this.sweepstakesService.checkUser(data)
.then(function(value){
    this.eligible = value;
});

Upvotes: 3

Related Questions