How to call service function in a controller with AngularJS? - angularjs

I'm trying to call a function from a service in a controller but I get an error saying that the thing I'm calling isn't a function. I'm new to AngularJS so I'm not exactly sure what I'm doing wrong. So, what's the correct way to call a service function in a controller?
I'm trying to call getCurrentUserInfo in the ProfileCtrl
.service('AuthService', function($http, Backand){
function getCurrentUserInfo() {
return $http({
method: 'GET',
url: baseUrl + "users",
params: {
filter: JSON.stringify([{
fieldName: "email",
operator: "contains",
value: self.currentUser.name
}])
}
}).then(function (response) {
if (response.data && response.data.data && response.data.data.length == 1)
return response.data.data[0];
});
}
})
.controller('ProfileCtrl', ['$scope', '$ionicSideMenuDelegate', 'AuthService', function($scope, $ionicSideMenuDelegate, AuthService) {
AuthService.getCurrentUserInfo().then(function(response){
$scope.user = response.data.data;
});
// function getCurrentUserInfo() {
// AuthService.getCurrentUserInfo()
// .then(function (result) {
// $scope.user = result.data;
// });
// }
}])

You need to make it a property of this.
.service('AuthService', function($http, Backand){
this.getCurrentUserInfo = function() {
return $http({
method: 'GET',
url: baseUrl + "users",
params: {
filter: JSON.stringify([{
fieldName: "email",
operator: "contains",
value: self.currentUser.name
}])
}
}).then(function (response) {
if (response.data && response.data.data && response.data.data.length == 1)
return response.data.data[0];
});
}
})
Then in your controller
AuthService.getCurrentUserInfo(whatEverYourParamsAre)
Edit: Actually, let me provide a little bit of context. Angular applies the new function to every .service(....) you include in your controller. As we know, calling this.aFunction in a constructor function causes the new operator in javascript to treat the aFunction function as a property on the object your constructor returns.

Related

$scope assignment works in one case but in other

First Case
angular.module('tss.application').controller("UserspaceController", function($scope, $http)
{
$http(
{
url : "/dirlist",
method : "GET",
}).then(function successCallback(response)
{
$scope.lists = response;
},
function errorCallback(response)
{
window.alert("Dir list could not be get");
});
});
Second Case
angular.module('tss.application').controller("UserspaceController", function ($scope, $http)
{
$http.get('dirlist').success(function(data)
{
$scope.lists = data;
});
});
I am very new to Angularjs so this could be a stupid questions. Anyway,
the assignment of lists variable works in second case but in first. That is, the second can access the values of "lists" inside the controllers. I failed to understand what is wrong with the first case?
angular.module('tss.application').controller("UserspaceController", function($scope, $http)
{
$http(
{
url : "/dirlist",
method : "GET",
}).then(function successCallback(response)
{
$scope.lists = response.data;
},
function errorCallback(response)
{
window.alert("Dir list could not be get");
});
});
put $scope.lists = response.data;, will work
Try this:
angular.module('tss.application').controller("UserspaceController", function($scope, $http)
{
$http(
{
url : "/dirlist",
method : "GET",
}).then(function successCallback(response)
{
$scope.lists = response.data;
},
function errorCallback(response)
{
window.alert("Dir list could not be get");
});
});
The deprecated success() method passes two separate values for data and headers, but the promise interface using .then() passes only a single response value which has the data and headers as attributes.
The change to your code is simply the line:
$scope.lists = response.data;

Angular Factory dependency issue

I have 2 factories: ApiService and LocationService.
In ApiService i'd like to return the endpoint from an $http call that LocationService will use.
But it seems when the controller calls LocationService, it doesn't wait for the response from ApiService. Here is some snippet of code, in ApiService when I finally get it working I will cache it so I won't need to make a server call each time to get the endpoint:
services.factory("ApiService", ["$location", "$http", function ($location, $http) {
return {
getEndpointUrl: function () {
var endpoint;
$http({
method: 'GET',
url: '/site/apiendpoint'
}).then(function successCallback(response) {
endpoint = response.data;
console.log(endpoint);
return endpoint;
}, function errorCallback(response) {
console.error('Error retrieving API endpoint');
});
}
}
}]);
Here is the location service, it consumes ApiService:
services.factory("LocationService", ["$resource", "ApiService", function ($resource, apiService) {
var baseUri = apiService.getEndpointUrl();
return $resource(baseUri + '/location', {}, {
usStates: { method: 'GET', url: baseUri + '/location/us/states' }
});
}]);
When my controller tries to call LocationService.usStates the baseUri is undefined. What am I doing wrong here?
The reason is because your getEndpointUrl function is asynchronous, and it has no return value.
Since your LocationService uses $resource and depends on on the baseUri, I would suggest bootstrapping that data along with the initial page load and making it a constant like:
angular.module('yourModule').constant('baseUrl', window.baseUrl);
Then your service would inject it to create your resource:
services.factory("LocationService", ["$resource", "ApiService", "baseUrl", function ($resource, apiService, baseUrl) {
return $resource(baseUrl + '/location', {}, {
usStates: { method: 'GET', url: baseUrl + '/location/us/states' }
});
}]);
In ApiService, you're not actually returning a value from getEndpointUrl(). How about you return a promise from ApiService, and then consume that in LocationService in a synchronous fashion?
services.factory("ApiService", ["$location", "$http", function($location, $http) {
return {
getEndpointUrl: function() {
var endpoint;
return $http({
method: 'GET',
url: '/site/apiendpoint'
});
}
}
}]);
services.factory("LocationService", ["$resource", "ApiService", function($resource, apiService) {
return {
getLocations: function() {
return apiService.getEndpointUrl().then(function successCallback(response) {
var baseUri = response.data;
return $resource(baseUri + '/location', {}, {
usStates: { method: 'GET', url: baseUri + '/location/us/states' }
});
}, function errorCallback(response) {
console.error('Error retrieving API endpoint');
});
}
};
}]);
And then in your controller:
LocationService.getLocations().then(function(data) {
$scope.statesResult = data.result.states;
});

Ionic. Using $http giving error Cannot read property 'protocol' of undefined

This question is related to another one.
Before I did added $ionicPlatform, my service working just fine, but now there is something wrong with $http.
Here is example of injectables:
(function () {
"use strict";
angular.module('service', ['ionic'])
.service('BBNService', ["$http", "$localStorage", "$ionicPlatform",
function ($http, $localStorage, $ionicPlatform) {
And using of $http and $ionicPlatform
this.tips = function () {
var url;
$ionicPlatform.ready(function () {
if (window.Connection) {
if (navigator.connection.type == Connection.CELL_4G || navigator.connection.type == Connection.WIFI) {
if (this.getDayId = 0)//If Sunday - retrieve updated tips
url = this.host + "/tips/";
else
url = "data/tips.json";//If not - use saved data
}
}
});
var request = $http({
method: "GET",
url: url
}).then(
function mySucces(response) {
return response.data;
},
function myError(response) {
return response.data;
});
return request;
};
You need to send back the promise, doing a return response.data is not gonna work.
var deferred = $q.defer();
var request = $http({
method: "GET",
url: url
}).then(
function mySucces(response) {
deferred.resolve(response.data);
},
function myError(response) {
deferred.reject(response.data);
});
return deferred.promise;
And at the place where you consume this service:
BBNService.tips().then(
function(data) { //success call back with data },
function(data) { //error call back with data }
);
Please let me know if you need more explanation on using $q; always happy to give more details.

Ajax in AngularJS Service

Created an Angular Service:
calculator_app.service('FillOpportunity', function () {
this.fill_opportunity = function (path,scope) {
$.ajax({
url: 'opportunitycalculator/calculator/GetProducts?idstring=' + path,
type: "GET",
cache: false,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data)
{
scope.opportunity_data = data;
scope.$apply();
},
error: function () {
}
});
};
});
Called the service on ng-change of a dropdown:
FillOpportunity.fill_opportunity($scope.result_path,$scope);
The scope.opportunity_data is binded to the select in UI:
<select id="seloppurtunityproducts" name="selproducttype" multiple="" style="height:300px" ng-model="opportunity_products" ng-options="a for a in opportunity_data"></select>
On ng-Change, Ajax is called when I check in Network of Chrome, but the value is not updated in the select box.
Any inputs?
Don't use jQuery's ajax. Use the built in $http. Using $http automatically begins the digest cycle of angular's builtin compiler. If you must use jquery... then you'd have to call $scope.$apply(); every time there is a data change.
Service:
calculator_app.factory("calcService", ["$http", function($http) {
return {
getItem: function(url, items) {
return $http.get(url,
// query string like { userId: user.id } -> ?userId=value
{ params: items });
}
}
}]);
Inject the service into your controller and use:
calculator_app.controller("MainCtrl", ["calcService", "$scope", function(calcService, $scope) {
$scope.opportunity_data = [];
var payload = {
idstring: path
};
//call the service
calcService.getItem('path/to/calc/api', payload).then(function(response) {
$scope.opportunity_data = response.data;
}).catch(function(response) {
alert('error' + response.data);
});
}]);

How can I pass back a promise from a service in AngularJS?

I have some code in my controller that was directly calling $http to get data.
Now I would like to move this into a service. Here is what I have so far:
My service:
angular.module('adminApp', [])
.factory('TestAccount', function ($http) {
var TestAccount = {};
TestAccount.get = function (applicationId, callback) {
$http({
method: 'GET',
url: '/api/TestAccounts/GetSelect',
params: { applicationId: applicationId }
}).success(function (result) {
callback(result);
});
};
return TestAccount;
});
Inside the controller:
TestAccount.get(3, function (data) {
$scope.testAccounts = data;
})
How can I change this so rather than passing the result of success back it
passes back a promise that I can check to see if it succeeded or failed?
Make your service to return a promise and expose it to service clients. Change your service like so:
angular.module('adminApp', [])
.factory('TestAccount', function ($http) {
var TestAccount = {};
TestAccount.get = function (applicationId) {
return $http({
method: 'GET',
url: '/api/TestAccounts/GetSelect',
params: { applicationId: applicationId }
});
};
return TestAccount;
});
so in a controller you can do:
TestAccount.get(3).then(function(result) {
$scope.testAccounts = result.data;
}, function (result) {
//error callback here...
});

Resources