Calling service returning undefined - javascript

I am creating a service called ActiveUserProfileService, but when I call its function in a controller I get undefined as a result and I cannot figure out why. The strangest part is that, in the ActiveUserProfileService service, the information from the UserService is displayed through console.log, so I'm receiving the information, but after calling the ActiveUserProfileService in the controller, it gives me undifened. It seems like the data isn't passed around. Can someone help me ?
UserService.js:
(function () {
'use strict';
angular
.module('myApp')
.factory('UserService', UserService);
UserService.$inject = ['$http'];
/* #ngInject */
function UserService($http) {
var service = {
getAuthenticatedUser: getAuthenticatedUser,
getUserInformation: getUserInformation
};
return service;
function getUserInformation(idUser) {
return $http.post('api/user/details', {idUser: idUser});
}
function getAuthenticatedUser() {
return $http.get('api/user');
}
}
})();
ActiveUserProfileService.js
(function () {
'use strict';
angular
.module('myApp')
.factory('ActiveUserProfileService', ActiveUserProfileService);
ActiveUserProfileService.$inject = ['$http','UserService'];
/* #ngInject */
function ActiveUserProfileService($http, UserService) {
var service = {
isAccount: isAccount
};
return service;
////////////////
function isAccount(accountName) {
UserService.getAuthenticatedUser()
.then(function (response) {
var data = response.data;
UserService.getUserInformation(data.user.id)
.then(function (response) {
var userDetails = response.data;
console.log("It is");
console.log(accountName == userDetails.account_types[0].description_internal);
return accountName == userDetails.account_types[0].description_internal;
});
})
}
}
})();
My controller:
(function () {
'use strict';
angular
.module('myApp')
.controller('WizardController', WizardController);
WizardController.$inject = [
'UserService',
'ActiveUserProfileService'
];
/* #ngInject */
function WizardController(UserService,ActiveUserProfileService) {
var vm = this;
console.log("ActiveUserProfileService");
console.log(ActiveUserProfileService.isAccount("professional")); //is Returning me undefined
}
})
();

The point is, you're trying to return a value for isAccount inside another function, a callback. When you do that, you're returning a value to this function, and not isAccount itself, so isAccount will not return anything, undefined, then.
As you are calling an assynchronous method, then isAccount must be assynchronous as well,
Replace
function isAccount(accountName) {
UserService.getAuthenticatedUser()
.then(function (response) {
var data = response.data;
UserService.getUserInformation(data.user.id)
.then(function (response) {
var userDetails = response.data;
console.log("It is");
console.log(accountName == userDetails.account_types[0].description_internal);
return accountName == userDetails.account_types[0].description_internal;
});
})
}
with
function isAccount(accountName) {
var deferred = $q.defer();
UserService.getAuthenticatedUser()
.then(function (response) {
var data = response.data;
//when the user is loaded, then you resolve the promise you has already returned
UserService.getUserInformation(data.user.id)
.then(function (response) {
var userDetails = response.data;
console.log("It is");
console.log(accountName == userDetails.account_types[0].description_internal);
deferred.resolve(accountName == userDetails.account_types[0].description_internal);
return; //here is not isAccount return, but anonymous inner function 'function (response)', you got it?
});
});
return deferred.promise; //return as soon as creates the promise
}
For sure you'd have to inject $q service as well

Related

AngularJS service does not return value from http.get

can someone help me with this code? I have problem with return value, function in controller return only
var products = {"id": 3};
I want to collect value from http.get, can someone tell me how to do that??
Controller:
$scope.product = {};
$scope.init = function () {
$scope.loadProducts()
}
$scope.loadProducts = function () {
// $http.get("/products/list").then(function (resp) {
// $scope.products = resp.data;
// })
$scope.products = getListProducts.loadProducts();
}
Service
var myServices = angular.module('myServices', []);
myServices.service('getListProducts', ['$http', function ($http) {
var products = {"id": 3};
this.loadProducts = function () {
$http.get("/products/list").then(function (resp) {
products = resp.data;
})
return products;
}
}]);
you are returning products before http success , instead use promises and resolve when http success
$scope.product = {};
$scope.init = function () {
$scope.loadProducts()
}
$scope.loadProducts = function () {
// $http.get("/products/list").then(function (resp) {
// $scope.products = resp.data;
// })
$scope.productPromise = getListProducts.loadProducts();
productPromise..then(function (resp) {
$scope.products = resp.data;
});
}
Service
var myServices = angular.module('myServices', []);
myServices.service('getListProducts', ['$http', function ($http) {
var products = {"id": 3};
this.loadProducts = function () {
return $http.get("/products/list");
}
}]);
Make use of promises to enforce serialization of your async code.
Refactor your service method as:
this.loadProducts = function () {
var getProducts = new Promise(function(resolve,reject){
$http.get("/products/list").then(function (resp) {
resolve(resp.data);
})
});
return getProducts;
};
And your Controller method as:
getListProducts.loadProducts().then(function(data){
//success callback
$scope.products = data;
});
You can provide the error callbacks as well.
Hope this helps !
You should use promises to return values from your service.
You can use $q in your service. It would help functions to run asynchronously.
myServices.service('getListProducts', ['$http','$q', function ($http,$q) {
var products = {"id": 3};
this.loadProducts = function () {
var deferred = $q.defer();
$http.get("/products/list").then(function (resp) {
products = resp.data;
deferred.resolve(products);
},function(error){
deferred.reject(error);
});
return deferred.promise;
}
}]);
And Your method in controller should handle success and error callbacks :
$scope.loadProducts = function () {
getListProducts.loadProducts().then(function(response){
$scope.products=response;
},function(error){
//your processing logic
});
}
I hope this would help you.

AngularJS: could not access Object property in the controller

this is my object that get from a service.
this is my controller.
var user = useroneService.getLoggedUser(user);
console.log(user);
console.log(user.data);
I got a undefined when I try to access the data. How do I access to the Object data?
user.service.js
'use strict';
angular.module('app').service('userService',['authService', 'userTransformer','LoggedUser', function(authService, userTransformer, LoggedUser) {
this.getLoggedUser = function(user){
return authService.login(user).then(function (response) {
var loggedUser = userTransformer.transform(response.data);
});
};
}]);
logged.user.js
angular.module('app').value('LoggedUser', function () {
var LoggedUser = function () {
this.dispalyName = '';
this.token = '';
this.logged = false;
};
LoggedUser.prototype = {
};
});
user.transformer.js
angular.module('app').factory('userTransformer',['LoggedUser', function (LoggedUser) {
//logged user transform
var transformObject = function (response) {
var model = new LoggedUser();
angular.extend(model, response);
return model;
};
return {
transform: transformObject
};
}]);
flow
AuthService(get data)==>UserService(data transform to LoggedUser using the transformer)
==>LoginController
You are not returning a promise. Change your controller code to:
useroneService.getLoggedUser(user).then(function(data) {
var user = data;
console.log(user);
})
One more thing, you are not returning the response from your service:
return authService.login(user).then(function (response) {
var loggedUser = userTransformer.transform(response.data);
return loggedUser; //add this
});

Data not received by Controller from Service

My Service looks like
app.service('SupportService', function ($http, $q, $timeout) {
var data = {result:[]};
var getData = function() {
$http.get('/rest/report/logs')
.then(function (response) {
data.result = response.data.result;
console.log("received logs:" + JSON.stringify(response.data.result));
});
};
getData();
return {
data: data.result
};
});
and in my controller, I do
var init = function () {
$scope.logs = SupportService.data;
console.log("logs = " + $scope.logs);
};
init();
When I run this, All I see on console is
logs =
received logs:[{"lastUpdated":"1430433095000","fileName":"java_pid1748.hprof","size":"2826611251","location":"/logs/java_pid1748.hprof"},{"lastUpdated":"1430862157000","fileName":"processor-debug.log","size":"910693","location":"/logs/processor-debug.log"},{"lastUpdated":"1430861106000","fileName":"processor-debug.log.1","size":"10242519","location":"processor-debug.log.1"},{"lastUpdated":"1430862156000","fileName":"processor-error.log","size":"1015578","location":"/logs/processor-error.log"},{"lastUpdated":"1430861106000","fileName":"logs","size":"204","location":"/logs"},{"lastUpdated":"1430862154000","fileName":"error.log","size":"2420","location":"/error.log"},{"lastUpdated":"1430862149000","fileName":"output.log","size":"71","location":"/output.log"}]
As you could see logs are empty, how to I have it wait while data comes from SupportService?
Thanks
When you say $scope.logs = SupportService.data; that is happening instantly - before your $http call is completed. You need to wait for the $http call to complete then extract the data. Generally the best way to do this is to return the promise that the $http creates:
app.service('SupportService', function ($http, $q, $timeout) {
return {
getData: function() {
return $http.get('/rest/report/logs');
};
};
});
And wait for the promise to resolve in your controller:
var init = function () {
SupportService.getData().then(function(response){
$scope.logs = response;
console.log("logs = " + $scope.logs);
}
};
init();

Angular Global Variables

I've got the following code in my Angular app that sets a global user variable. I want to know if what I've written can be refactored to a better way. I don't know why but firing the setUser() function on app.run feels a bit clunky? Can the following be improved?
app.run()
app.run(function ($user) {
$user.setUser();
});
app.service('$user')
app.service('$user', ['$http', function ($http) {
var currentUser;
this.setUser = function () {
$http.get('/users/active/profile')
.success(function (user) {
currentUser = user;
})
.error(function () {
console.log('ERR');
})
}
this.getUser = function () {
return currentUser;
}
}]);
You could do something like this.
app.service('$user', ['$http', function ($http) {
var currentUser;
var usrSrv = {
setUser : function () {
currentUser = "test user";
console.log( "user Set" );
},
getUser : function() {
return currentUser;
}
};
usrSrv.setUser();
return usrSrv;
}]);
You may also want to look into using angular promises ( https://docs.angularjs.org/api/ng/service/$q), since this is a async call. Depending on the context and your design, you may want to change the service to just expose a getUser method, The getUser method will make the http call and return a promise that gets resolved when it has fetched the results from the server.
Try doing below:
(function () {
var userService = function ($http) {
var setUser = function () {
$http.get('/users/active/profile')
.success(function (user) {
var currentUser = user;
})
.error(function () {
console.log('ERR');
});
};
return {
currentUser: currentUser,
};
};
var module = angular.module("app");
module.factory("userService", userService);
}());

Using a factory and controller to return data

I have the following factory:
app.factory('clientFactory', function ($http) {
var factory = {};
factory.getClients = function () {
var url = "/tracker/api/client";
$http.get(url).then(function (response) {
return response.data;
});
};
factory.getClient = function (id) {
// TODO
};
factory.insertClient = function (firstName, lastName, city) {
// TODO
};
factory.deleteClient = function (id) {
// TODO
};
return factory;
});
And the controller:
app.controller('ClientController', function ($scope, clientFactory) {
$scope.clients = [];
init();
function init() {
$scope.clients = clientFactory.getClients();
}
$scope.insertCustomer = function () {
// TODO
};
$scope.deleteCustomer = function (id) {
// TODO
};
});
In my controller, 'clients' is always null. I've tried a couple of other approaches like what I see here but I got an error that 'success cannot be called on null' and if I make it past that error, my success function is never called.
What am I missing here?
In your controller, you are treating the getClients method as if it were synchronous. Remember that when you do $http.get, a promise is returned. You need to return that promise to the controller, so it can call .then with a method which will handle a successful result.
Your getClients method needs to look like this:
factory.getClients = function () {
var url = "/tracker/api/client";
return $http.get(url);
};
And I believe your init method needs to look like this:
function init() {
clientFactory.getClients().then(function(response) {
$scope.clients = response.data;
});
}
Try that out!

Categories

Resources