Not able to call service from angularJS controller - angularjs

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();
...

Related

Angularjs interceptor: Interceptor in not work

Hi this below is my code from angularjs
The first part of the code shows exactly how I make the request to php which returns me data when there is code with an error when there is a problem.
When it returns me an error code, for example 401, the frontend explodes with an error and everything breaks.
As far as I understand, I have to use an interceptor so that I can catch the error number and not make an error.
I can't do this interception.
app.js
app.factory('httpRequester', function ($http, $route) {
var promise;
var myService = {
async: function (myData) {
//Create my obj for request
var req = {
method: myData.Method,
url: 'https://**********/' + url,
headers: {
'X-API-KEY': '**************',
'KEY': myData.Authentication.AccessToken
},
data: myData
};
promise = $http(req).then(function (response) {
if (response.data === 'permission denied') {
window.location.href = '#/';
} else {
return response;
}
});
return promise;
}
};
return myService;
});
//set interceptor in app.js
var interceptorApp = angular.module('interceptorApp', []);
interceptorApp.config(function($httpProvider) {
$httpProvider.interceptors.push('genericInterceptor');
});
Please help me with my problem, how to set interceptor work.
//Function for set error and success after request
var testInterceptor = function ($q)
{
return {
request: function (config)
{
//console.log('request started...');
},
requestError: function (rejection)
{
console.log(rejection);
// Contains the data about the error on the request and return the promise rejection.
return $q.reject(rejection);
},
response: function (result)
{
// console.log('data for ' + result.data.name + ' received');
//If some manipulation of result is required before assigning to scope.
result["testKey"] = 'testValue';
console.log('request completed');
return result;
},
responseError: function (response)
{
// console.log('response error started...');
//Check different response status and do the necessary actions 400, 401, 403,401, or 500 eror
return $q.reject(response);
}
}
}

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

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');
}
});
}
};
}]);

How to provide delay in ng-controller

As soon as Html page gets loaded, it calls SuperCategoryController, where i am assigning supercategories to $scope variable.
$scope.SuperCategories = SuperCategoryService.GetSuperCategories();
But as this controller is depends on service, which in turn calls the http request. so at the time pf assignment http request is not completed. so $scope.SuperCategories is getting assiged to undefined.
sampleApp.service('SuperCategoryService', ['$http', function ($http){
var URL = 'http://localhost/cgi-bin/superCategory.pl';
var SuperCategories;
$http({
method: 'POST',
url: URL,
data: "action=GET",
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).
success(function (data) {
alert (data);
if (data != null || data != 'undefined') {
SuperCategories = data;
}
})
.error(function (error) {
alert (error.message);
//$scope.status = 'Unable to retrieve super categories' + error.message;
});
//simply returns the SuperCategories list
this.GetSuperCategories = function () {
//alert (SuperCategories);
return SuperCategories;
}
}]);
sampleApp.controller('SuperCategoryController', ['$scope', 'SuperCategoryService', function ($scope, SuperCategoryService){
$scope.SuperCategories = SuperCategoryService.GetSuperCategories();
$scope.LoadSuperCategoryMapping = function()
{
alert ($scope.SelectedSuperCategory.id);
}
}]);
How to solve this problem in proper way.
I haven't tried this code myself but I would approach a solution using factory and a promise to make sure the data has been loaded. Something along these lines:
sampleApp.factory('SuperCategoryService', ['$http', function ($http){
return {
GetSuperCategories: function () {
var URL = 'http://localhost/cgi-bin/superCategory.pl';
return $http.get(URL);
}
}
}]);
sampleApp.controller('SuperCategoryController', ['$scope', 'SuperCategoryService', function ($scope, SuperCategoryService){
$scope.SuperCategories = function() {
SuperCategoryService.GetSuperCategories()
.then(function(d) {
if (d.data != undefined) {
// Your data should be loaded here
console.log(d.data);
$scope.SuperCategories = d.data;
}
})
.error(function(data, status) {
// Errors here
});
}
}]);

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

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
}
})

Resources