Reputation: 1338
I want to call a service from a controller to login a user. In order to test the general concept the services at this point should just return a JSON-object with some mock data.
If I press the login button, I receive an error message like this:
Error: loginService.loginTest(...).then is not a function
$scope.login@http://localhost/Clickstar/app/controller/loginController.js:15:3
Wa.prototype.functionCall/<@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular.min.js:162:24
Mc[c]</<.compile/</</<@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular.min.js:178:390
zd/this.$get</h.prototype.$eval@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular.min.js:101:141
zd/this.$get</h.prototype.$apply@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular.min.js:101:418
Mc[c]</<.compile/</<@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular.min.js:178:370
Xc/c/<@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular.min.js:27:145
q@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular.min.js:7:378
Xc/c@http://ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular.min.js:27:129
angular.min.js:84:35
Here is my code
login.html
<div>
<div>
<form method="post" ng-submit="login()">
<input name="username" type="text" ng-model="username" placeholder="username"><br>
<input name="password" type="password" ng-model="password" placeholder="password"><br>
<input type="submit" value="Login" class="center-button">
</form>
</div>
<div ng-show="Login.success">
Username: {{Login.loginUsername}} <br>
Password: {{Login.loginPassword}} <br>
UserID: {{Login.usernID}} <br>
</div>
</div>
loginService.js
app.service('loginService', function($http, $q) {
this.loginTest = function(username, password)
{
var dummyData = { "username" : username,
"password" : password,
"userID" : 007,
"loginStatus" : 1
};
return dummyData;
};
return this;
});
loginController.js
app.controller('loginController', function ($scope, loginService) {
var vm = this;
vm.loginUsername = null;
vm.loginPassword = null;
vm.usernID = null;
vm.success = null;
$scope.login = function(){
vm.loginUsername = $scope.username;
vm.loginPassword = $scope.password;
loginService.loginTest($scope.username, $scope.password)
.then(function(dummyData){
vm.loginUsername = dummyData.username;
vm.loginPassword = dummyData.password;
vm.usernID = dummyData.userID;
if(dummyData.loginStatus == 1){
vm.success = true;
}
else{
vm.success = false;
}
})
};
});
So what is the problem with my code and how can I fix it?
Upvotes: 0
Views: 41
Reputation: 3663
The problem is that your mock login server is not returning a promise, which you are expecting within your controller.
You can change your loginTest
method to instead return a promise by doing:
return $q(function(resolve, reject) {
resolve(dummyData);
});
I would like to point out that your login service is returning the username and password which seems unnecessary, you should really be making a request to the server which would inform you whether or not the username/password was valid. You could mock a service that does this as follows:
app.service('loginService', function($http, $q) {
var dummyData = {
"username": username,
"password": password,
"userID": 007,
"loginStatus": 1
};
this.loginTest = function(username, password) {
return $q(function(resolve, reject) {
if (username === dummyData.username && password === dummyData.password) {
resolve({
userId: dummyData.userID,
loginStatus: dummyData.loginStatus
});
} else {
reject("Incorrect username or password");
}
});
};
return this;
});
If you are deploying this to browsers that don't support ES6 then you need to use the defered API instead.
var deferred = $q.defer();
deferred.resolve(someData);
return deferred.promise;
is synonymous to
return $q(function(resolve, reject) { resolve(someData); }
Upvotes: 2
Reputation: 932
You have not associated controller to your form. The form tag should be
<form method="post" ng-submit="login()" ng-controller="loginController">
Alternatively you can also associate the controller to the div tag that contains the form.
Refer the AngularJS documentation here
Upvotes: 0
Reputation: 133433
You are returning JSON object where as it expects a promise from loginService
.
Change the code the loginTest
as
app.service('loginService', function($http, $q) {
this.loginTest = function(username, password) {
var dummyData = {
"username": username,
"password": password,
"userID": 007,
"loginStatus": 1
};
var deferred = $q.defer();
deferred.resolve(dummyData);
return deferred.promise;
};
return this;
});
Upvotes: 1