I have this service to retrieve a list of cars from a WebAPI server :
angular.module('MyServices')
.service('carService', ['$http', '$rootScope',
function ($http, $rootScope) {
this.getList =function(userName, ticket)
{
$rootScope.$emit('My.OnBusy');
$http.get('api/car'
, { params: {userName: userName} }
).success(function (data) {
$rootScope.$emit('My.OnIdle');
if (data[0] && data[0].Name == "Error")
{
$rootScope.$emit("My.OnError", data[0].Model);
return {};
}
return data;
}).error(function (data, status, headers, config) {
$rootScope.$emit('My.OnIdle');
$rootScope.$emit("My.OnError", "Error in communication with server.");
return {};
});
}
}]
);
And in the controller I use it like this :
angular.module('MyControllers')
.controller('carController', function CarController($rootScope, $scope, $http, carService) {
$scope.loadCars = function (userName, ticket) {
$scope.Cars = carService.getList(userName, ticket);
}
$scope.loadCars($rootScope.user.email, '');
});
But the $scope.Cars is Undefined after the cal to getList. I tried to use "then" when I call the service but it was unsuccessful.
Saying that I want to handle success and error of the operation in the service itself, how can I get final result in the controller?
For future reference :
Service should be like this :
angular.module('MyServices')
.service('carService', ['$http', '$rootScope', '$q'
function ($http, $rootScope, $q) {
this.getList =function(userName, ticket)
{
$rootScope.$emit('My.OnBusy');
var deferred = $q.defer();
$http.get('api/car'
, { params: {userName: userName} }
).success(function (data) {
$rootScope.$emit('My.OnIdle');
if (data[0] && data[0].Name == "Error")
{
$rootScope.$emit("My.OnError", data[0].Model);
deferred.reject(data[0].Address);
//return {};
}
deferred.resolve(data);
//return data;
}).error(function (data, status, headers, config) {
$rootScope.$emit('My.OnIdle');
$rootScope.$emit("My.OnError", "Error in communication with server.");
deferred.reject("Error in communication with server.");
//return {};
});
return deferred.promise;
}
}]
);
And now "then" works in the controller :
angular.module('MyControllers')
.controller('carController', function CarController($rootScope, $scope, $http, carService) {
$scope.loadCars = function (userName, ticket) {
carService.getList(userName, ticket).then(function (data) {
$scope.Cars = data;
});;
}
$scope.loadCars($rootScope.user.email, '');
});
Related
Upgrade to angularjs version 1.7 and this code does not compile
app.factory('LoginService', function ($http) {
return {
login: function (param, callback) {
$http.post(url, param)
.success(callback)
.error(function (data, status, headers, config) {
});
}
};
});
On the controller I make the call to the service LoginService
function LoginController($http, $location, LoginService, blockUI) {
var vm = this;
LoginService.usuario(
{login: vm.username, clave: vm.password},
function (data, status, headers, config) {
vm.resultado = data;
if (vm.resultado == "True") {
window.location = "/Home/Index";
} else {
vm.error = 'Usuario o password incorrecto';
}
});
};
I want to know how the function is called from the controller because it implemented the http.post service using .then
app.factory('LoginService', function ($http) {
return {
login: function (data) {
$http.post(url, data)
.then(function (resultado) {
debugger;
if (resultado.data === "True") {
return resultado.data;}
else {
console.log("NO");}
});
}};
});
I suggest you get familiar with a AngularJS $q service and its Promise API.
You LoginService.login(...) method should return the Promise from $http.post(...):
app.factory('LoginService', function ($http) {
return {
login: function (data) {
return $http.post(url, data)
.then(function(response) {
return response.data;
});
});
Then, your Controller can access the returned data via the resolved Promise:
function LoginController(LoginService) {
var vm = this;
LoginService.login({login: vm.username, clave: vm.password})
.then(function (result) {
// handle result here...
});
the solution would be this:
function LoginController($scope,$window,$q,LoginService) {
$scope.fnBusqueda = function () {
var promesas = [
obtenerLogin()
];
$q.all(promesas).then(function (promesasRes) {
var oArrayResponse = promesasRes;
if ((oArrayResponse.length > 0)) {
$scope.respuesta = oArrayResponse[0];
if ($scope.respuesta == "True") {
window.location = "/Home/Index";
} else {
$cope.error = 'Usuario o password incorrecto';
}
}
});
};
function obtenerLogin() {
var defered = $q.defer();
var promise = defered.promise;
LoginService.login(url_valida_login, '{login:X,clave:X}').then(function (response) {
defered.resolve(response);
}).catch(function (data) {
defered.resolve([]);
})
return promise;
}
}
LoginController.js
var MyApp = angular.module('MyApp', []);
MyApp.controller("LoginController",
["$scope", "$rootScope",
function ($scope , dataService) {
$scope.user = "sample";
$scope.checkUser = function () {
dataService.getUserData($scope.user).then(
function (results) {
$scope.userLoginInfo = results.userInfo;
},
function (results) {
$rootScope.showAlert(results, "There is a problem when trying to get user details.");
});
};
}]);
My DataService.js
MyApp.factory("dataService",
["$http", "$rootScope", "$q",
function ($http, $rootScope,$q) {
var dataService = {};
var getUserData = function (username) {
var promise = $http.get(baseUrl()+"/Controllers/UserDetails/?username=" + username)
.success(function (data, status, headers, config) {
return data;
})
.error(function (data, status, headers, config) {
return data;
});
return promise;
}
return {
getUserData: getUserData
}
}]);
i have included all .js files via bundleconfig .on calling dataService.getUserData in login controller , the described error occurs.
following is the stack trace
"TypeError: Object doesn't support property or method 'getUserData'\n at $scope.checkUser (http://localhost:58949/app/Controllers/LoginController.js:41:9)
at fn (Function code:2:195)\n at expensiveCheckFn (http://localhost:58949/Scripts/angular.js:16123:11)\n at callback (http://localhost:58949/Scripts/angular.js:26490:17)\n at Scope.prototype.$eval (http://localhost:58949/Scripts/angular.js:17913:9)\n at Scope.prototype.$apply (http://localhost:58949/Scripts/angular.js:18013:13)\n at Anonymous function (http://localhost:58949/Scripts/angular.js:26495:17)\n at n.event.dispatch (http://localhost:58949/Scripts/jquery-2.2.3.min.js:3:7481)\n at r.handle (http://localhost:58949/Scripts/jquery-2.2.3.min.js:3:5547)"
any help is greatly appreciated
You have not injected dataService so in your scenario instead of accessing "dataService" it is accesing "$rootScope"
try this :
// controller
var MyApp = angular.module('MyApp', []);
MyApp.controller("LoginController", ["$scope", "$rootScope", "dataService",
function($scope, $rootScope, dataService) {
$scope.user = "sample";
$scope.checkUser = function() {
dataService.getUserData($scope.user).then(
function(results) {
$scope.userLoginInfo = results.userInfo;
},
function(results) {
$rootScope.showAlert(results, "There is a problem when trying to get user details.");
});
};
}
]);
Also in your service
following line /Controllers/UserDetails/?username= seems to be incorrect, We pass query parameter in following way :
// "/Controllers/UserDetails?username="
// Service
MyApp.factory("dataService", ["$http", "$rootScope", "$q",
function($http, $rootScope, $q) {
var dataService = {};
var getUserData = function(username) {
var promise = $http.get(baseUrl() + "/Controllers/UserDetails?username=" + username)
.success(function(data, status, headers, config) {
return data;
})
.error(function(data, status, headers, config) {
return data;
});
return promise;
}
return {
getUserData: getUserData
}
}
]);
Inject the dataService.
MyApp.controller("LoginController",
["$scope", "$rootScope","dataService",
function ($scope ,rootScope dataService) {
. .
}
If the dataService not injected properly, hence it throws the error.
I have a problem with getting value from service in my controller.
I get the value from API using service:
angular.module('app').factory('service',
['$q', '$rootScope', '$timeout', '$http',
function ($q, $rootScope, $timeout, $http) {
// create user variable
var user = null;
// return available functions for use in the controllers
return ({
isLoggedIn: isLoggedIn,
getUserStatus: getUserStatus,
login: login,
getEmail: getEmail
});
function isLoggedIn() {
if(user) {
return true;
} else {
return false;
}
}
function getUserStatus() {
return $http.get('/user/status')
// handle success
.success(function (data) {
if(data.status){
user = true;
} else {
user = false;
}
})
// handle error
.error(function (data) {
user = false;
});
}
function login(username, password) {
// create a new instance of deferred
var deferred = $q.defer();
// send a post request to the server
$http.post('/user/login',
{username: username, password: password})
// handle success
.success(function (data, status) {
if(status === 200 && data.status){
user = true;
deferred.resolve();
} else {
user = false;
deferred.reject();
}
})
// handle error
.error(function (data) {
user = false;
deferred.reject();
});
// return promise object
return deferred.promise;
}
function getEmail() {
// create a new instance of deferred
var deferred = $q.defer();
$http.get('/email/'+$rootScope.username)
.success(function (data) {
console.log(data);
deferred.resolve();
})
.error(function (data) {
deferred.reject();
})
return deferred.promise;
}
}]);
and I'm trying to get and use value in the controller:
angular.module('app')
.controller('myController', ['$rootScope', '$scope', '$state', '$http', '$q', 'service', function ($rootScope, $scope, $state, $http, $q, service) {
$scope.email;
$scope.getEmail = function() {
// call getEmailFromDB from service
service.getEmail()
// handle success
.then(function (data) {
$scope.email = data; //here I got undefined
console.log($scope.email);
})
// handle error
.catch(function () {
$scope.error = true;
$scope.errorMessage = "wrong#mail.com";
});
};
$scope.getEmail();
}]);
but in the controller there is undefined value.
In my console:
Regarding the documentation of $q, I use then() function in service and controller.
Does anybody know where is the problem?
you forgot to send your result in your service like this
deferred.resolve(data);
In your code you are not returning anything with the promise, to do that you must call deferred.resolve(data) or deferred.reject(data).
Instead of creating a deferred object, you can simply return the $http request.
Example:
function getEmail() {
return $http.get('/email/'+$rootScope.username).then(
function success(data){
console.log(data);
return data;
},
function error(data){
console.error(data);
}
);
}
Also notice that .success() and .error() are deprecated, you should use .then() and pass the success and error functions.
i have my authservice as given below ,
myApp.factory('Authentication',
['$rootScope', '$location', 'URL', '$http', '$q',
function ($rootScope, $location, URL, $http, $q) {
var myObject = {
authwithpwd: function (user) {
var dfd = $q.defer();
$http
.post('Mart2/users/login', {email: user.email, password: user.password})
.then(function (res) {
return dfd.resolve(res.data);
}, function (err) {
return dfd.reject(err.data);
});
return dfd.promise;
} //login
};
return myObject;
}]); //factory
And i'm using that service in user service as follows :
myApp.factory('UserService',
['$rootScope', '$location', 'URL', '$http', '$q', 'Authentication',
function ($rootScope, $location, URL, $http, $q, $Authentication) {
var myObject = {
login: function (user) {
$Authentication.authwithpwd(user).then(function (regUser) {
console.log(regUser);
}).catch(function (error) {
$rootScope.message = error.message;
});
},
getUserToken: function () {
return $rootScope.currentUser.apiKey;
},
isLogged: function () {
if ($rootScope.currentUser) {
return true;
} else {
return false;
}
}
//login
};
return myObject;
}]); //factory
I am very new to angular js . While writing service and calling that service from controller i have put a console debug in user service which is showing its returning object .i am getting object if i do console.log(regUser) ? any idea why ?
To get the object you need to do change your myObject declaration. Basically you need to return a promise from the login function and then write a callback to get the resolved data.
myApp.factory('UserService',
['$rootScope', '$location', 'URL','$http','$q','Authentication',
function($rootScope,$location, URL,$http,$q,$Authentication) {
var myObject = {
login: function(user) {
var defer = $q.defer();
$Authentication.authwithpwd(user).then(function(regUser) {
console.log(regUser);
defer.resolve(regUser);
}).catch(function(error) {
$rootScope.message = error.message;
defer.reject(regUser);
});
return defer.promise;
},
getUserToken:function() {
return $rootScope.currentUser.apiKey;
},
isLogged:function() {
if($rootScope.currentUser){
return true;
} else {
return false;
}
}//login
};
return myObject;
}]); //factory
To extract the object from controller or from some other service you need to write a callback
UserService.login(user)
.then(function (data) {
$scope.data = data;
}, function (error) {
$scope.error = error;
});
Also in the Authentication service you can just do a 'dfd.resolve' instead of 'return dfd.resolve'; since you are already returning the dfd.promise.
I have created a fiddler here
I have a service that retrieves data via REST. I want to store the resulting data in service level variable for use in multiple controllers. When I put all the REST logic directly into controllers everything works fine but when I attempt to move the retrieval / storing of data into a service the controller is not being updated when the data comes back. I've tried lots of different ways of maintain the binding between service and controller.
Controller:
myApp.controller('SiteConfigCtrl', ['$scope', '$rootScope', '$route', 'SiteConfigService',
function ($scope, $rootScope, $route, SiteConfigService) {
$scope.init = function() {
console.log("SiteConfigCtrl init");
$scope.site = SiteConfigService.getConfig();
}
}
]);
Service:
myApp.factory('SiteConfigService', ['$http', '$rootScope', '$timeout', 'RESTService',
function ($http, $rootScope, $timeout, RESTService) {
var siteConfig = {} ;
RESTService.get("https://domain/incentiveconfig", function(data) {
siteConfig = data;
});
return {
getConfig:function () {
console.debug("SiteConfigService getConfig:");
console.debug(siteConfig);
return siteConfig;
}
};
}
]);
View:
<div class="span4" ng-controller="SiteConfigCtrl">
<header>
<h2>
{{site.title}}
</h2>
</header>
I would write it with promise factory:
myApp.factory('SiteConfigService', ['$http', '$rootScope', '$timeout', 'RESTService', '$q'
function ($http, $rootScope, $timeout, RESTService, $q) {
var siteConfig = {} ;
RESTService.get("https://domain/incentiveconfig", function(data) {
siteConfig = data;
});
// or just
// var siteConfig = RESTService.get("https://domain/incentiveconfig");
return {
getConfig:function () {
var deferred = $q.defer();
deferred.resolve(siteConfig);
return deferred.promise;
}
};
}
]);
Controller side
SiteConfigService.getConfig()
.then(function (result) {
$scope.site = result;
}, function (result) {
alert("Error: No data returned");
});
Solution based on Maxim's answer above - JsFiddle - http://jsfiddle.net/acb98sm/2pQ6A/6/
var myApp = angular.module('myApp',[]);
myApp.controller('SiteConfigCtrl', ['$scope', '$rootScope', '$route', 'SiteConfigService',
function ($scope, $rootScope, $route, SiteConfigService) {
SiteConfigService.getConfig()
.then(function (result) {
console.log("results are in ");
console.log(result);
$scope.site = result.data;
}, function (result) {
alert("Error: No data returned");
});
}
]);
myApp.factory('SiteConfigService', ['$http', '$rootScope', '$timeout', 'RESTService', '$q',
function ($http, $rootScope, $timeout, RESTService, $q) {
var siteConfigFn = RESTService.get("http://graph.facebook.com/616366118/", function(data) {
console.log("SiteConfigService returns");
});
return {
getConfig:function () {
var deferred = $q.defer();
deferred.resolve(siteConfigFn);
return deferred.promise;
}
};
}
]);
myApp.$inject = ['$scope', 'SiteConfigService', 'RESTService'];
myApp.factory('RESTService',
function ($http) {
return {
get:function (url, callback) {
return $http.get(url, {withCredentials:false}).
success(function (data, status, headers, config) {
callback(data);
}).
error(function (data, status, headers, config) {
console.log("failed to retrieve data");
});
},
post:function (url, data, callback) {
return $http.post(url, data, {withCredentials:true}).
success(function (data, status, headers, config) {
callback(data);
}).
error(function (data, status, headers, config) {
console.log("failed to retrieve data");
});
}
};
}
);