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?
This question is related to
javascript
angularjs
promise
angular-promise
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;
});
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;
});
};
}]);
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>
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;
]);
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 );
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.
Source: Stackoverflow.com