How to return a resolved promise from an AngularJS Service using $q?

后端 未结 7 1620
Happy的楠姐
Happy的楠姐 2020-12-05 17:23

My service is:

myApp.service(\'userService\', [
  \'$http\', \'$q\', \'$rootScope\', \'$location\', function($http, $q, $rootScope, $location) {
    var defe         


        
相关标签:
7条回答
  • 2020-12-05 17:35

    From your service method:

    function serviceMethod() {
        return $timeout(function() {
            return {
                property: 'value'
            };
        }, 1000);
    }
    

    And in your controller:

    serviceName
        .serviceMethod()
        .then(function(data){
            //handle the success condition here
            var x = data.property
        });
    
    0 讨论(0)
  • 2020-12-05 17:36

    Return your promise , return deferred.promise.
    It is the promise API that has the 'then' method.

    https://docs.angularjs.org/api/ng/service/$q

    Calling resolve does not return a promise it only signals the promise that the promise is resolved so it can execute the 'then' logic.

    Basic pattern as follows, rinse and repeat
    http://plnkr.co/edit/fJmmEP5xOrEMfLvLWy1h?p=preview

    <!DOCTYPE html>
    <html>
    
    <head>
      <script data-require="angular.js@*" data-semver="1.3.0-beta.5" 
            src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
      <link rel="stylesheet" href="style.css" />
      <script src="script.js"></script>
    </head>
    
    <body>
    
    <div ng-controller="test">
      <button ng-click="test()">test</button>
    </div>
    <script>
      var app = angular.module("app",[]);
    
      app.controller("test",function($scope,$q){
    
        $scope.$test = function(){
          var deferred = $q.defer();
          deferred.resolve("Hi");
          return deferred.promise;
        };
    
        $scope.test=function(){
          $scope.$test()
          .then(function(data){
            console.log(data);
          });
        }      
      });
    
      angular.bootstrap(document,["app"]);
    
    </script>
    

    0 讨论(0)
  • 2020-12-05 17:44

    For shorter JavaScript-Code use this:

    myApp.service('userService', [
      '$q', function($q) {
        this.initialized = $q.when();
        this.user = {
          access: false
        };
        this.isAuthenticated = function() {
          this.user = {
            first_name: 'First',
            last_name: 'Last',
            email: 'email@address.com',
            access: 'institution'
          };
          return this.initialized;
        };
      }
    ]);
    

    You know that you loose the binding to userService.user by overwriting it with a new object instead of setting only the objects properties?

    Here is what I mean as a example of my plnkr.co example code (Working example: http://plnkr.co/edit/zXVcmRKT1TmiBCDL4GsC?p=preview):

    angular.module('myApp', []).service('userService', [
        '$http', '$q', '$rootScope', '$location', function ($http, $q, $rootScope, $location) {
        this.initialized = $q.when(null);
        this.user = {
            access: false
        };
        this.isAuthenticated = function () {
            this.user.first_name = 'First';
            this.user.last_name = 'Last';
            this.user.email = 'email@address.com';
            this.user.access = 'institution';
            return this.initialized;
        };
    }]);
    
    angular.module('myApp').controller('myCtrl', ['$scope', 'userService', function ($scope, userService) {
        $scope.user = userService.user;
        $scope.callUserService = function () {
            userService.isAuthenticated().then(function () {
                $scope.thencalled = true;
            });
        };
    }]);
    
    0 讨论(0)
  • 2020-12-05 17:47

    Here's the correct code for your service:

    myApp.service('userService', [
      '$http', '$q', '$rootScope', '$location', function($http, $q, $rootScope, $location) {
    
        var user = {
          access: false
        };
    
        var me = this;
    
        this.initialized = false;
        this.isAuthenticated = function() {
    
          var deferred = $q.defer();
          user = {
            first_name: 'First',
            last_name: 'Last',
            email: 'email@address.com',
            access: 'institution'
          };
          deferred.resolve(user);
          me.initialized = true;
    
          return deferred.promise;
        };
      }
    ]);
    

    Then you controller should align accordingly:

    myApp.run([
      '$rootScope', 'userService', function($rootScope, userService) {
        return userService.isAuthenticated().then(function(user) {
          if (user) {
            // You have access to the object you passed in the service, not to the response.
            // You should either put response.data on the user or use a different property.
            return $rootScope.$broadcast('login', user.email);  
          } else {
            return userService.logout();
          }
        });
      }
    ]);
    

    Few points to note about the service:

    • Expose in a service only what needs to be exposed. User should be kept internally and be accessed by getters only.

    • When in functions, use 'me' which is the service to avoid edge cases of this with javascript.

    • I guessed what initialized was meant to do, feel free to correct me if I guessed wrong.

    0 讨论(0)
  • 2020-12-05 17:52

    Try this:

    myApp.service('userService', [
        '$http', '$q', '$rootScope', '$location', function($http, $q, $rootScope, $location) {
          var deferred= $q.defer();
          this.user = {
            access: false
          };
          try
          {
          this.isAuthenticated = function() {
            this.user = {
              first_name: 'First',
              last_name: 'Last',
              email: 'email@address.com',
              access: 'institution'
            };
            deferred.resolve();
          };
        }
        catch
        {
            deferred.reject();
        }
    
        return deferred.promise;
      ]);
    
    0 讨论(0)
  • 2020-12-05 17:54

    How to simply return a pre-resolved promise in Angular

    Resolved promise:

    return $q.when( someValue );    // angular 1.2+
    return $q.resolve( someValue ); // angular 1.4+, alias to `when` to match ES6
    

    Rejected promise:

    return $q.reject( someValue );
    
    0 讨论(0)
提交回复
热议问题