Passing an argument to a service for use with $http.get() - angularjs

I've created a service which consumes an API. I need to call this service from my controller with an argument that's passed in from a text input on a form.
myAppServices.factory('apiService', function ($http, $q) {
return {
getDocuments: function () {
return $http.get('/api/documents/',
{
params: {
id: '2' // this should not be hardcoded
}
})
.then(function (response) {
if (typeof response.data == 'object') {
return response.data;
} else {
// invalid response
return $q.reject(response.data);
}
}, function (response) {
// something went wrong
return $q.reject(response.data);
});
},
}
My controller looks like this currently...
myApp.controller('homeController', function ($scope, apiService) {
var docs = function () {
apiService.getDocuments()
.then(function (data) {
$scope.docs = data; //console.log(data);
}, function (error) {
// promise rejected ... display generic no data found on table
console.log('error', error);
});
};
}
And my input is simply...
<input type="text" class="form-control" placeholder="Enter ID" ng-model="id">
How can I get the value entered into this input into my service so that I can return the data based on the ID value put into the text input?

You need to pass the parameter to the service method, there is some suggestions that you can consider it.
1-) the promise api and the method on your service.
The right way to use the $q is using the deferred object inself. your service could be like.
myAppServices.factory('apiService', function ($http, $q) {
return {
getDocuments: function (id) {
var deferred = $q.defer();
$http({
method: 'GET',
url: '/api/documents/',
params: {id: id}
}).success(function (response) {
if (typeof response.data == 'object') {
deferred.resolve(response.data);
} else {
deferred.reject(response.data);
}
}).error(function (response) {
deferred.reject(response.data);
});
return deferred.promise;
}
}
})
2-) your controller could be like.
myApp.controller('homeController', function ($scope, apiService) {
$scope.getDocs = function () {
apiService.getDocuments($scope.id)
.then(function (data) {
$scope.docs = data; //console.log(data);
}, function (error) {
// promise rejected ... display generic no data found on table
console.log('error', error);
});
};
});

You can just pass additional parameters in your service definition. Then when you use it in your controller, you can pass additional values.
myAppServices.factory('apiService', function ($http, $q) {
return {
getDocuments: function (param1, param2) {
}

Should be something along these lines:
In your controller
apiService.getDocuments($scope.id).then...
In your service
getDocuments: function (idVar) {
return $http.get('/api/documents/',
{
params: {
id: idVar // this should not be hardcoded
}
})

Related

Http Function in factory not work in controller when use the "then"

I am trying to call the http function of Factory in controller ,it does not work when I use the .then
My code is as follows:
module :
var brandlistmodule = angular.module('newApp')
factory :
brandlistmodule.factory('BrandListFactory',["$http","$routeParams",function($http,$routeParams){
console.log(2)
return {
a: function(response){
console.log('1');
return $http.get("/restful_api/category_1/?format=json").then(function(response){
console.log('3');
return response.data;
});
},
b: function(response){
return $http.get("/restful_api/category_refer_a/?format=json").then(function(response){
return response.data;
});
},
c: function(response){
return $http.get("/restful_api/brand_test_search/?format=json").then(function(response){
result = response.data
return result;
});
},
}
}])
controller:
brandlistmodule.controller('brandlistCtrl', ['BrandListFactory','$scope','$rootScope','$http',function (BrandListFactory,$scope,$rootScope,$http) {
$scope.$on('$viewContentLoaded', function () {
$rootScope.category = function(){
BrandListFactory.a.success(function(data){
console.log('9');
$rootScope.category =data
});
};
In the console it only can show the "2",if I change the controller as follows ,it will work properly
brandlistmodule.controller('brandlistCtrl', ['BrandListFactory','$scope',function (BrandListFactory,$scope) {
$scope.$on('$viewContentLoaded', function () {
BrandListFactory.BrandCategoryList()
your problem is you're calling Then() inside the factory...so what you can do is :
1 - NO CALLING THEN .. but RETURN ALL YOUR $http request to the caller of the Factory .. like:
brandlistmodule.factory('BrandListFactory',["$http","$routeParams",function($http,$routeParams){
console.log(2)
return {
a: function(response){
console.log('1');
return $http.get("/restful_api/category_1/?format=json");
},
b: function(response){
return $http.get("/restful_api/category_refer_a/?format=json");
},
c: function(response){
return $http.get("/restful_api/brand_test_search/?format=json");
},
}
}])
2- use $q and make by yourself the asyncron chain .. like:
brandlistmodule.factory('BrandListFactory',["$http","$routeParams","$q",function($http,$routeParams,$q){
console.log(2)
return {
a: function(response){
var deferred = $q.defer();
console.log('1');
return $http.get("/restful_api/category_1/?format=json").then(function(response){
console.log('3');
deferred.resolve( response.data);
}).catch(function(err){
deferred.reject(err);
});
return deffered.promise;
}
// and same for others
}
}])
I would suggest to creat a Service which is responsible for all of your http calls something like this
.service('HttpService', ['$rootScope', '$http', 'Ls', 'CommonService', 'DateService', function ($rootScope, $http, Ls, CommonService, DateService) {
return {
CallService: function (url, callback) {
$http.get(url)
.success(function (data, status) {
callback(data, status);
}).error(function (data, status) {
callback(data, status);
});
}
}
});
If you pass the parameter callback into the HttpService.CallService then you can call the callback in the success or error function of the http.get call.
For example in the Controller you can do
HttpService.CallService('/restful_api/category_refer_a/?format=json', function (data) {
console.log(data)
//do something with your data
});
So in your example you could do:
$scope.$on('$viewContentLoaded', function () {
HttpService.CallService('/restful_api/category_refer_a/?format=json', function (data) {
console.log('9');
$rootScope.category =data
});
});
or you simply change your calls to
b: function(callback){
return $http.get("/restful_api/category_refer_a/?format=json").then(function(response){
callback(response.data);
});
},
and
BrandListFactory.b(function(data){
console.log('9');
$rootScope.category =data
});
Hope this helps you

Angular Js - Why I am getting Undefiend in controller while I am getting data from service?

I have made a service and I am getting the data but it does not return any thing to controller.
My service. js file
app.factory('countryService', function ($http) {
return {
getCountries: function () {
$http.get('http://abc/countries')
.success(function (data) {
console.log(data);
})
.error(function (data) {
console.log(data);
});
}
};
});
and here is my controller
$scope.countries = function () {
$scope.countries_data = countryService.getCountries();
console.log($scope.countries_data);
};
What is my mistake ?
You might need to do some structural changes like following
app.factory('countryService', function ($http) {
return {
getCountries: function () {
return $http.get('http://abc/countries'); //just return promise
}
};
});
Let service return the promise, Do other proceedings inside the controller,Define success callback and faiure callback for the same
$scope.countries = function () {
$scope.countries_data = countryService.getCountries().then(success, failure); // callbaks
};
function success(response){
console.log(response); // logs the results
}
function failure(response){
console.log(response); // logs the errors if any
}
Hope this will help
In your service:
app.factory('countryService', function ($http) {
return {
getCountries: function () {
return $http.get('http://abc/countries') // add return this service
.success(function (data) {
console.log(data);
})
.error(function (data) {
console.log(data);
});
}
};
});
In controller:
$scope.countries = function () {
countryService.getCountries().then(function(res){
$scope.countries_data = res;
console.log($scope.countries_data);
});
};

Getting Cannot read property 'then' of undefined when using .fromFnPromise in angular-datatables

//the controller that creates the datatable
app.controller('AdminListCtrl', function ($scope, $compile, DTOptionsBuilder, DTColumnBuilder, adminService) {
var vm = this;
function stateChange(iColumn, bVisible) {
console.log('The column', iColumn, ' has changed its status to', bVisible);
}
//vm.dtOptions = DTOptionsBuilder.fromSource('http://localhost/api-v1/admin')
vm.dtOptions = DTOptionsBuilder.fromFnPromise(function() {
return adminService.loadAdmin();
})
.withPaginationType('full_numbers')
.withOption('createdRow', createdRow)
// Add Bootstrap compatibility
.withBootstrap()
// Active ColVis plugin
.withColVis()
// Add a state change function
.withColVisStateChange(stateChange)
// Exclude the last column from the list
.withColVisOption('aiExclude', [2])
// Add Table tools compatibility
.withTableTools('scripts/vendor/datatables/TableTools/swf/copy_csv_xls_pdf.swf')
.withTableToolsButtons([
'copy',
'print', {
'sExtends': 'collection',
'sButtonText': 'Save',
'aButtons': ['csv', 'xls', 'pdf']
}
]);
//adminService to request for all administrators
app.factory('adminService', ['ApiService', function (ApiService) {
return {
loadAdmin: function () {
ApiService.get("admin").then(function (response) {
if (response) {
if (response.success === true) {
return response;
}else{
console.log(response);
}
}else {
console.log('error request ');
}
});
}
};
}]);
//apiservice to interact with api
app.factory('ApiService', function ($http, $q, $localStorage) {
return {
get: function (apiresource) {
var returnData = $q.defer();
$http({
url: api + apiresource,
method: 'GET',
headers: {"Auth-Token": $localStorage.user_data.auth_token}
})
.success(function (data) {
returnData.resolve(data);
})
.error(function (error) {
returnData.resolve();
});
return returnData.promise;
}};
});`enter code here`
When ever I am in that view it throws this errorCannot read property 'then' of undefined. I am following examples from these two sources
http://www.revillweb.com/angularjs-by-example/4-sharing-data-with-angularjs-services/
http://l-lin.github.io/angular-datatables/#/withPromise
You need to return promise object (result of ApiService.get("admin") call) from loadAdmin method.
Also make sure you don't "swallow" rejections inside of the then (in console.log branches) - what happens when you unintentionally handle errors by not passing it further. For this return rejected promise or simply throw error, so that rejection will propagate further down the promise chain:
app.factory('adminService', ['ApiService', function (ApiService) {
return {
loadAdmin: function () {
return ApiService.get("admin").then(function (response) {
if (response) {
if (response.success === true) {
return response;
} else{
console.log(response);
throw response;
// or custom error object: throw {message: 'Error loadAdmin', response}
}
} else {
console.log('error request ');
throw new Error('error request');
}
});
}
};
}]);

Why do i have to use return twice and how does it work?

I wrote a wrapper for the $http service in angular using a service. Why do i have to return bothe the http call and my result to have it available in a controller?
this is the function in the service:
this.fetchData = function(url, parameters)
{
if (parameters)
{
return $http.get(url, {params: parameters}).then(
function (response) {
console.log(response);
return response.data.data;
},
function (response) {
console.log(response);
});
}
else
{
return $http.get(url).then(
function (response) {
console.log(response);
},
function (response) {
console.log(response);
}
);
}
}
and this is where i call it in the controller:
test.fetchData('/jewelry-room/move-user.action', {user:2000, task:7}).then(
function (response) {
console.log(response);
},
function (response) {
console.log(response);
}
);
Because what you return from the factory is a promise: return $http.get().then(). Since your factory has the callback function inside then, so the promise is resolved. In this case, the function inside controller then block will not be called.
You need to return again in order to have access to the response data inside the controller.
Alternatively, just return $http.get() from the factory.
You could just return the promise to your controller by using $q:
var fetchData = function (url, params) {
if (params) {
var deferred = $q.defer();
$http.get(url, {params: params}).success(deferred.resolve).error(deferred.reject)
return deferred.promise;
} else {
var deferred = $q.defer();
$http.get(url).success(deferred.resolve).error(deferred.reject)
return deferred.promise;
}
}
Then inside your controller you can handle the promise.

Not able to call service from angularJS controller

I've defined 1 service to fetch the category and controller to call the service.
var req = {
method: 'POST',
url: 'http://localhost/cgi-bin/superCategory.pl',
headers: { 'Content-Type': undefined },
data: { action: 'GET' }
};
sampleApp.factory('SuperCategoryService', ['$http', function ($http){
return {
GetSuperCategories: function () {
return $http(req)
.then(
function(response)
{
if (typeof response.data === 'object')
{
alert ('right');
//return response.data;
}
else
{
alert ('wrong');
// invalid response
//return $q.reject(response.data);
}
},
function(response) {
alert ('again worng');
// something went wrong
//return $q.reject(response.data);
});
}
};
}]);
sampleApp.controller('SuperCategoryController', ['$scope', 'SuperCategoryService', function ($scope, SuperCategoryService){
$scope.SuperCategories = function() {
SuperCategoryService.GetSuperCategories()
.then(function(d) {
alert (d);
if (d != undefined) {
alert ('in');
// Your data should be loaded here
console.log(d.data);
alert (d);
$scope.SuperCategories = d.data;
}
else
{
alert ('Here');
}
})
.error(function(data, status) {
// Errors here
});
}
}]);
Even though i am calling the service in controller, but its not hitting to any of the alert in service. (Not even error case)
What can be the problem? Any help will be highly appreciated.
See this $http documentation.Here you did a mistake in calling method of $http.
sampleApp.factory('SuperCategoryService', ['$http', function ($http){
return {
GetSuperCategories: function () {
return $http.post('http://localhost/cgi-bin/superCategory.pl',{ action: 'GET' });
};
}]);
Please see demo here http://jsbin.com/tahigerube/1/edit
you need to call your $scope.SuperCategories to execute it
...
$scope.SuperCategories();
...

Resources