Prometheus
Prometheus

Reputation: 33625

Returning a promise in a factory

Hoe can I return a promise in a factory to use in my controller given the example below:

Factory:

  angular
    .module('security.authorisation')
    .factory('AuthService', [
      '$http',
      AuthService
    ]);


  function AuthService($http, Endpoints, toastr) {
    var authService = {};
    // Login function.
    authService.login = function (user, success, error) {
      var login_url = Endpoints.getUrl("login");
      $http.post(login_url)

        .success(function (data) {

      }).then(function (temp) {
       console.log("suc");
      }, function (err) {
        console.log("err");
      });

    };



    return authService;
  }

Login controller:

(function () {
  'use strict';

  angular
    .module('login')
    .controller('LoginController', [
      '$scope',
      'AuthService',
      LoginController
    ]);

  function LoginController($scope, AuthService) {


    $scope.submit = function submit() {

      $scope.app = AuthService.initModel;
      AuthService.login($scope.app)

        .then(function (greeting) {
          alert('Success: ' + greeting);
        }, function (reason) {
          alert('Failed: ' + reason);
        });


    }

  }
})();

I get the error:

TypeError: Cannot read property 'then' of undefined

Upvotes: 0

Views: 650

Answers (3)

Aer0
Aer0

Reputation: 3907

You need to use a deferred object. First of all inject $q into your login Factory.

After that, change up your login function:

hint: As far as I know, .success() should be deprecated, so only use .then() for success and error callbacks.

authService.login = function(user, success, error) {
  var login_url = Endpoints.getUrl("login");
  var deferred = $q.defer();
  $http.post(login_url)
    .then(function(temp) {
      console.log("suc");
      deferred.resolve(temp);
    }, function(err) {
      console.log("err");
    });
  //toaster.pop('success', "title", "text");
  return deferred;
};

In your controller you should use the following:

AuthorisationService.login($scope.app).then(function(success) {
  // do your stuff here as you please
}

This should solve your problem and you should handle promises the correct way.

Upvotes: 1

Yonatan Vainer
Yonatan Vainer

Reputation: 453

read about $q... 1. inject $q to your service 2. create deferred object 3. use .then when calling to your service

function returningPromise(){
var deferred = $q.defer();

callToWhateverYouWantWithReturningPromise().then(function(data){
deferred.resolve(data);
}, function(error){
deferred.reject(error);
});
return deferred.promise

Upvotes: 1

It seems that You forgot to return your promise

    authService.login = function (user, success, error) {
      var login_url = Endpoints.getUrl("login");
      return $http.post(login_url)

        .success(function (data) {

      }).then(function (temp) {
       console.log("suc");
      }, function (err) {
        console.log("err");
      });
      //toaster.pop('success', "title", "text");
    };

Upvotes: 4

Related Questions