I have the following angular app (JSFiddle):
HTML
<form data-ng-app="jsApDemo" data-ng-controller="loginCtrl">
<label for="username">Username:</label>
<input type="text" id="username" data-ng-model="username" />
<br />
<label for="password">Password:</label>
<input type="password" id="password" data-ng-model="password" />
<br />
<button type="submit" data-ng-click="executeLogIn()">Log in</button>
<br />
<label for="authstatus">Authentication status:</label>
<input type="text" id="authstatus" readonly value="{{ authStatus }}" />
</form>
It is a simple login form, and when the user clicks submit, I want to execute a function in controller loginCtrl
. loginCtrl
calls a service that makes the actual authentication process.
JavaScript
// the controller and its module
angular.module('jsApDemo', ['Core'])
.controller('loginCtrl', ['$scope', 'Connection', function ($scope, Connection) {
$scope.authStatus = 'unauthenticated';
$scope.executeLogIn = function () {
$scope.authStatus = 'authenticating';
Connection.sessionInitialize({
username: $scope.username,
password: $scope.password
}, function (error, status) {
if (!error) {
/***************************
* THIS LINE IS THE CULPRIT
***************************/
$scope.authStatus = status;
}
});
};
}]);
// the service and its module
angular.module('Core', []).service('Connection', function () {
this.sessionInitialize = function (options, callback) {
if (!options || !options.username || !options.password) {
callback('Username, and password are mandatory', null);
return;
}
setTimeout(function () {
callback(null, 'authenticated');
}, 1000);
};
});
In service Connection
, I have used a setTimeout
(Note: setTimeout
was used as a placeholder for an asynchronous call. My original code did not have a setTimeout
. It had a call to an asynchronous function in a third party library. I could not make the JSFiddle with that call included in the code. So I replaced the call to that library with a setTimeout
to demonstrate the asynchronous nature of the code).
Problem arises when I try to access $scope
from within the callback function to Connection.sessionInitialize
. After debugging I found out that following line does not work:
/***************************
* THIS LINE IS THE CULPRIT
***************************/
$scope.authStatus = status;
It seems like a scoping issue, but a simple console.log($scope)
statement prior to this line shows that $scope
has the correct value. However the textbox #authstatus
which has its value
attribute bound to $scope.authStatus
does not change.
What am I doing wrong?
Thanks to @RahilWazir, I came up with a solution: