Как вернуть разрешенное обещание из сервиса AngularJS, используя $q?
Моя служба:
myApp.service('userService', [
'$http', '$q', '$rootScope', '$location', function($http, $q, $rootScope, $location) {
var deferred;
deferred = $q.defer();
this.initialized = deferred.promise;
this.user = {
access: false
};
this.isAuthenticated = function() {
this.user = {
first_name: 'First',
last_name: 'Last',
email: 'email@address.com',
access: 'institution'
};
return deferred.resolve();
};
}
]);
Я вызываю это в моем файле config
через:
myApp.run([
'$rootScope', 'userService', function($rootScope, userService) {
return userService.isAuthenticated().then(function(response) {
if (response.data.user) {
return $rootScope.$broadcast('login', response.data);
} else {
return userService.logout();
}
});
}
]);
Однако он жалуется, что then
не является функцией. Разве я не возвращаю свое твердое обещание?7 ответов:
Из вашего метода обслуживания:
function serviceMethod() { return $timeout(function() { return { property: 'value' }; }, 1000); }
И в вашем контроллере:
serviceName .serviceMethod() .then(function(data){ //handle the success condition here var x = data.property });
Как просто вернуть предварительно разрешенное обещание в Angular
Решенное обещание:
return $q.when( someValue ); // angular 1.2+ return $q.resolve( someValue ); // angular 1.4+, alias to `when` to match ES6
Отвергнутое обещание:
return $q.reject( someValue );
Верни свое обещание, верни отсроченное.обещать.
Это promise API, который имеет метод "тогда".Https://docs.angularjs.org/api/ng/service/$q
Вызов resolve не возвращает обещание, он только сигнализирует о том, что пообещайте, что обещание будет выполнено, чтобы оно могло выполнить логику "тогда".
Основная схема следующим образом, промыть и повторить
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>
Вот правильный код для вашего сервиса:
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; }; } ]);
Тогда вы контроллер должен выровнять соответственно:
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(); } }); } ]);
Несколько моментов, чтобы отметить об услуге:
Выставляйте в сервисе только то, что должно быть выставлено. Пользователь должен быть сохранен внутри и доступен только геттерам.
Когда в функциях, используйте 'me', который является сервисом, чтобы избежать крайних случаев этого с javascript.
Я догадался, что инициализированный должен был сделать, не стесняйтесь поправь меня, если я ошибся.
Чтобы вернуть решенное обещание, вы можете использовать:
return $q.defer().resolve();
Если вам нужно что-то решить или вернуть данные:
return $q.defer().resolve(function(){ var data; return data; });
Для более короткого JavaScript-кода используйте следующее:
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; }; } ]);
Вы знаете, что вы теряете привязку к userService.пользователь, перезаписывая его новым объектом вместо установки только свойств объектов?
Вот что я имею в виду в качестве примера моего plnkr.co пример кода (рабочий пример: 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; }); }; }]);
Попробуйте это:
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; ]);