Reputation: 8690
I am trying to evaluate an expression in an if statement to return true
or false
. The function's evaluation depends on $http
promises, of which the documentation out there is plentiful—so I'm confident I can get this figured out.
However, I noticed something odd in my console, and that is that it seems the .success
callback is being ran twice, as the console is outputting the output from the success callback twice (i.e. the call was a success
is being logged twice)!
From looking at the code, my understanding would be that the save()
causes securityCheck.checkLogin()
to log undefined
, the if statement to evaluate to false (thereby logging function returned false
), and then the promise to return with the call was a success
to be logged once. Why is it being logged twice?
script
angular.module('login', ['security'])
.directive('loginDirective', ['$parse', 'securityCheck', function($parse, securityCheck) {
return {
scope: true,
link: function(scope, element, attrs, form) {
scope.save = function() {
console.log(securityCheck.checkLogin());
//evaluates to undefined, promise not returned yet
if (securityCheck.checkLogin()) {
console.log("function returned true");
} else {
console.log("function returned false");
}
}
}
};
}]);
angular.module('security', [])
.factory('securityCheck', ['$q', '$http', function ($q, $http) {
var security = {
checkLogin: function() {
$http.get('https://api.mongolab.com/api/1/databases/lagrossetete/collections/avengers?apiKey=j0PIJH2HbfakfRo1ELKkX0ShST6_F78A')
.success(function(data, status, headers, config) {
console.log('the call was a success!');
})
.error(function(data, status, headers, config) {
console.log('the call had an error.');
});
}
};
return security;
}]);
html
<html ng-app="login">
<body>
<login-directive ng-click="save()">click me</login-directive>
</body>
</html>
plnkr: http://plnkr.co/edit/tM7eHniDRvCLhzAw7Kzo?p=preview
Thanks!
Upvotes: 1
Views: 1031
Reputation: 193311
Well remove console.log(securityCheck.checkLogin());
and request will be issued only once. However this is only minor problem with your code. Real one is that you treat AJAX request as if it was synchronous, however it's not. checkLogin
method doesn't return true/false
it returns promise object, and asynchronously.
You should check for auth result inside of then
callback:
link: function(scope, element, attrs, form) {
scope.save = function() {
securityCheck.checkLogin().then(function(check) {
if (check) {
console.log("function returned true");
} else {
console.log("function returned false");
}
});
}
}
You also need to make factory method return promise:
angular.module('security', [])
.factory('securityCheck', ['$q', '$http', function ($q, $http) {
var security = {
checkLogin: function() {
return $http.get('https://api.mongolab.com/api/1/databases/lagrossetete/collections/avengers?apiKey=j0PIJH2HbfakfRo1ELKkX0ShST6_F78A')
.success(function(data, status, headers, config) {
console.log('the call was a success!');
return data;
})
.error(function(data, status, headers, config) {
console.log('the call had an error.');
});
}
};
return security;
}]);
Demo: http://plnkr.co/edit/Kj8PkLMv3PsLfe9fsaRo?p=preview
Upvotes: 1
Reputation: 228
You call the console.log once in your directive and then once again in your factory function.
// Here in the directive
scope.save = function() {
console.log(securityCheck.checkLogin());
// And then here in the service
.success(function(data, status, headers, config) {
console.log('the call was a success!');
Although different commands, they both return the same value
Upvotes: 1
Reputation: 15719
You do realize, you are calling checkLogin()
method twice:
console.log(securityCheck.checkLogin());
//evaluates to undefined, promise not returned yet
if (securityCheck.checkLogin()) {
This causes $http.get()
to be executed twice, and so is your success
implementation.
Upvotes: 2