50

My service is:

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 protected]',
 access: 'institution'
 };
 return deferred.resolve();
 };
 }
]);

I'm calling this in my config file via:

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();
 }
 });
 }
]);

However, it complains that then is not a function. Aren't I returning the resolved promise?

Bergi
670k161 gold badges1k silver badges1.5k bronze badges
asked May 9, 2014 at 14:40

7 Answers 7

108

How to simply return a pre-resolved promise in AngularJS

Resolved promise:

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

Rejected promise:

return $q.reject( someValue );
answered Jun 11, 2015 at 11:08
Sign up to request clarification or add additional context in comments.

1 Comment

This is exactly what I was looking for. A nice short way to return a static value when stubbing out http service calls.
35

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>
serge
15.4k42 gold badges144 silver badges239 bronze badges
answered May 9, 2014 at 14:42

3 Comments

How will the promise get resolved then? The .then will never get triggered
@Shamoon deferred.resolve(); is resolved in the moment you call it because there is no value given in. I would suggest instead of write deferred.resolve("Hi"); just write deferred.resolve(); to get a resolved empty promise. But you could also use $q.when(); to get a resolved thenable empty promise ;-).
IMHO this is better than the accepted answer, which by using $timeout to generate a promise that will be resolved is failing to show the mechanics of manually creating and resolving promises.
21

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
 });
answered May 9, 2014 at 14:52

7 Comments

@BenjaminGruenbaum Yes, you are correct, I was unaware that $timeout actually returns a promise, serviceMethod can be shortened to: return $timeout(function() { return {property: 'value'}; }, 1000);
This may work, but it's certainly not a recommended approach for returning promises
@BenjaminGruenbaum I did, now returning the promise which $timeout generates.
Very well, I retracted my -1.
ah ok, but I still agree with his sentiment even if for a different reason! I appreciate a downvote is disheartening, and that we could just use upvotes to help the good content float to the top, but in this case I do feel your answer is not helpful, because it fails to explain the mechanics of $q and instead presents an abstraction of $q. Someone new to promises, or like me familiar with promises but new to Angular, could get totally the wrong end of the stick!
|
4

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 protected]',
 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.

answered May 9, 2014 at 18:56

Comments

2

To return a resolved promise, you can use:

return $q.defer().resolve();

If you need to resolve something or return data:

return $q.defer().resolve(function(){
 var data;
 return data;
});
answered Jun 3, 2015 at 19:59

1 Comment

I've posted an even shorter version.
1

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 protected]',
 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 protected]';
 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;
 });
 };
}]);
answered Sep 23, 2014 at 7:00

Comments

0

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 protected]',
 access: 'institution'
 };
 deferred.resolve();
 };
 }
 catch
 {
 deferred.reject();
 }
 return deferred.promise;
 ]);
answered May 9, 2014 at 15:14

1 Comment

Could someone tell me why this is marked for downvote?

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.