In my app.config i need to retrieve a value from a service but i have an error message : UserServiceProvider.getUser is not a function. The goal is to allow the user to access some pages only if he is a part of a list.
Here's my service code :
var app = angular.module('myApp');
app.service('UserService', '$http', '$q', function(){
userService.getUser = function () {
var deferred = $q.defer();
return $http.get(userUrl + "getUserName")
.success(function (data) {
deferred.resolve(userService.userName = data);
console.log(data);
//alert('Success loading user');
}).error(function (error) {
deferred.reject(error);
//alert('Error loading user' + error.message);
})
return deferred.promise;
}
return userService;
});
My config :
app.config(function(UserServiceProvider){
UserServiceProvider.getUser()
.then(function (data) {
console.log(UserServiceProvider.userName);
});
});
Related
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 am first time using angular JS so kindly bear my question. While creating service in angular JS I have to write var deferred = $q.defer(); and then return deferred.promise; in every method of service which use $http()
Is there any shorthand or alternative way to do so?
for eg:
(function() {
'use strict';
angular
.module('app')
.service('AuthService', function($q, $http, $interval, $timeout, BASE_URL) {
var service = {
login: function(formdata) {
var deferred = $q.defer();
$http.post(BASE_URL + '/api/getLogin', formdata).then(function(response) {
deferred.resolve(response);
}, function(err) {
deferred.reject(err);
});
return deferred.promise;
},
signup: function(formdata) {
var deferred = $q.defer();
$http.post(BASE_URL + '/api/register', formdata).then(function(response) {
deferred.resolve(response);
}, function(err) {
deferred.reject(err);
});
return deferred.promise;
},
forgot: function(formdata) {
var deferred = $q.defer();
$http.post(BASE_URL + '/api/forgot', formdata).then(function(response) {
deferred.resolve(response);
}, function(err) {
deferred.reject(err);
});
return deferred.promise;
}
}
return service;
});
here you can see I have to rewrite the same line of code in every method of service
use $http methods without any other code:
return $http.post(BASE_URL + '/api/getLogin', formdata)
all $http methods return promise by default
When I get the data from the service using getAllGenres everything works fine, but when I try to pass the parameter vm.id the data is of type undefined. Please help. P.S. from an Angular new comer
genresService:
angular.module('movies.services', [])
.factory('genresService', ['$http', function ($http) {
function callback () {
// TODO: Implement callback function
}
function getAllGenres (callback) {
var url = '/api/genres';
$http.get(url)
.success(function (data) {
callback(data);
})
.error(function (error) {
console.log(error);
})
}
function getGenreById (id) {
var url = '/api/genres/' + id;
console.log(id);
$http.get(url)
.success(function (data) {
callback(data);
})
.error(function (error) {
console.log(error);
})
}
return {
getAllGenres: getAllGenres,
getGenreById: getGenreById
};
}]);
GenresController:
.controller('GenresController', ['$scope', 'genresService',
function ($scope, genresService) {
var vm = this;
genresService.getAllGenres(function (data) {
vm.genres = data;
});
}])
GenresDetailsController:
.controller('GenreDetailsController', ['$routeParams', 'genresService',
function ($routeParams, genresService) {
var vm = this;
vm.id = $routeParams.id;
genresService.getGenreById(vm.id, function (data) {
console.log(data);
})
}]);
Have this scenario when I make a request via $http in the first service, and then I want to manipulate the data in other service. For some reassons my returned object is empty. Any advice ?
.factory('widgetRestService',['$http','$log',function($http,$log){
var serviceInstance = {};
serviceInstance.getInfo = function(){
var request = $http({method: 'GET', url: '/rest/widgets/getListInfoDashboards'})
.then(function(success){
serviceInstance.widgets = success.data;
$log.debug('serviceInstance.widgets SUCCESS',serviceInstance.widgets);
},function(error){
$log.debug('Error ', error);
$log.debug('serviceInstance.widgets ERROR',serviceInstance.widgets);
});
return request;
};
serviceInstance.getAllWidgets = function () {
if (serviceInstance.widgets) {
return serviceInstance.widgets;
} else {
return [];
}
};
return serviceInstance;
}])
.factory('OtherService',['widgetRestService','$log', function(widgetRestService, $log){
widgetRestService.getInfo();
// and now I want to return widgetRestService.widgets [{things},{things},{things}]
return widgetRestService.getAllWidgets(); // returns []
}])
Result: [ ]
You must wait for your HTTP request to complete before trying to access the data that it returns. You can do this by accessing getAllWidgets within a then attached to the Promise returned by getInfo.
.factory('OtherService', ['widgetRestService','$log', function(widgetRestService, $log) {
return widgetRestService.getInfo().then(function () {
return widgetRestService.getAllWidgets();
});
}])
Consume OtherService somewhere:
OtherService.then(function (widgets) {
// do something with `widgets`...
});
It seems you have to return promise instead of response to get the data from another service.
serviceInstance.getInfo = function(){
var deferred = $q.defer();
$http({method: 'GET', url: '/rest/widgets/getListInfoDashboards'})
.then(function(success){
deferred.resolve(success.data);
},function(error){
$log.debug('Error ', error);
$log.debug('serviceInstance.widgets ERROR',serviceInstance.widgets);
});
return deferred.promise;
};
widgetRestService.getInfo() is returning a promise, so you have to wait for its resolution:
.factory("OtherService", ["widgetRestService", "$log", "$q"
function (widgetRestService, $log, $q) {
var deferred = $q.defer();
widgetRestService.getInfo().then(function () {
// only here, you're sure `serviceInstance.widgets` has been set (unless an error occurred when requesting the api)
deferred.resolve(widgetRestService.getAllWidgets());
});
return deferred.promise;
}])
Then, e.g. in a controller:
.controller("SomeController", ["$scope", "OtherService"
function ($scope, OtherService) {
OtherService.then(function (allWidgets) {
$scope.allWidgets = allWidgets;
});
}])
I have:
this.isAuthenticated = function() {
var deferred;
deferred = $q.defer();
$http({
url: "" + endpoints.authService + "api/v1/session/check",
method: 'GET',
withCredentials: true
}).success(function(response) {
var user;
if (response.authenticated === true) {
user = response;
}
return deferred.resolve(response);
}).error(function(data, status, headers, config) {
deferred.reject(data);
return $rootScope.$broadcast('api-error', 'Cannot access authentication service');
});
return deferred.promise;
};
Assuming that the endpoint is down, apparently it tries to do the call infinitely. Is this some known Angular behavior? And can I disable it?
No factory making http call when your controller invoking that call please see here: http://plnkr.co/edit/u7YSD8gkbOSKN32SU62P?p=preview. It's rather you controller keeping call factory function.
var app = angular.module('plunker', []);
app.factory('dataService', function($http, $q, $rootScope) {
var endpoints = {
authService: "ttest"
};
this.isAuthenticated = function() {
var deferred;
deferred = $q.defer();
$http({
url: "" + endpoints.authService + "api/v1/session/check",
method: 'GET',
withCredentials: true
}).success(function(response) {
var user;
if (response.authenticated === true) {
user = response;
}
return deferred.resolve(response);
}).error(function(data, status, headers, config) {
deferred.reject(data);
return $rootScope.$broadcast('api-error', 'Cannot access authentication service');
});
return deferred.promise;
};
return this;
});
app.controller('MainCtrl', function($scope, dataService) {
$scope.$on('api-error', function(a, b){
alert(b);
});
dataService.isAuthenticated();
});
just put this deferred.resolve(response); instead of return deferred.resolve(response);
and also remove return from :
return $rootScope.$broadcast('api-error', 'Cannot access authentication service');