How to do error handling when fetching data in angularjs service - angularjs

This code fetches categories and give them to controller.
sampleApp.factory('SCService', function($http, $q) {
var SuperCategories = [];
var SCService = {};
SCService.GetSuperCategories = function() {
var req = {
method: 'POST',
url: SuperCategoryURL,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: "action=GET"
};
if ( SuperCategories.length == 0 ) {
return $http(req).then(function (response) {
SuperCategories = response.data;
return SuperCategories;
});
}else {
return $q.when(SuperCategories);
}
}
return SCService;
});
I think code is perfect until there is no error in http request.
My query is how to do error handling (try catch or something like that), in case if server have some issue or may be cgi-script have some issue and not able to server the request.

Angular promises use a method catch for that.
return $http(req).then(function (response) {
SuperCategories = response.data;
return SuperCategories;
}).catch(function(error) {
// Do what you want here
});
You should use also finally :
return $http(req).then(function (response) {
SuperCategories = response.data;
return SuperCategories;
}).catch(function(error) {
// Do what you want here
}).finally(function() {
// Always executed. Clean up variables, call a callback, etc...
});

Write like
return $http(req).then(function (response) {
//success callback
},
function(){
//Failure callback
});

Use callback methods from controller Like
Controller.js
service.GetSuperCategories(function (data) {console.log('success'},function (error){console.log('error'});
service.js
sampleApp.factory('SCService', function($http, $q) {
var SuperCategories = [];
var SCService = {};
SCService.GetSuperCategories = function(successMethod,errorMethod) {
var req = {
method: 'POST',
url: SuperCategoryURL,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: "action=GET"
};
return $http(req).then(successMethod(data),
errorMethod(error));
}
return SCService;
});

You can use the .success and .error methods of $http service, as below
$http(req).success(function(data, status, headers){
// success callback: Enters if status = 200
}).error(function(status, headers){
// error callback: enters otherwise
});

Related

Angularjs $http then is not working properly

I get a value of "True" in my response. How come my debugger and alert and AccessGranted() in the .then of my $http is not being invoked. Below is my Script:
app.controller("LoginController", function($scope, $http) {
$scope.btnText = "Enter";
$scope.message = "";
$scope.login = function() {
$scope.btnText = "Please wait...";
$scope.message = "We're logging you in.";
$http({
method: 'post',
url: '/Login/Login',
data: $scope.LoginUser
}).then(function (response) {
debugger;
alert(response.data);
if (response.data == "True") {
AccessGranted();
} else {
$scope.message = response.data;
$scope.btnText = "Enter";
}
},
function (error) {
$scope.message = 'Sending error: ' + error;
});
}
$scope.AccessGranted = function() {
window.location.pathname("/Home/HomeIndex");
}
});
This is in my HomeController
public ActionResult HomeIndex()
{
var am = new AuditManager();
var auditModel = new AuditModel()
{
AccountId = 0,
ActionDateTime = DateTime.Now,
ActionName = "Home",
ActionResult = "Redirected to Home"
};
am.InsertAudit(auditModel);
return View("Index");
}
Please see image for the response I get.
seems like your approach is wrong
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
Try this,
$http({
method: 'post',
url: '/Login/Login',
data: $scope.LoginUser
})
.then(function (response) {
console.log(response);
},
function (error) {
console.log(error);
});
And check your browser console for logs or any errors
Make sure the response is application/json content type, and content is json.
You can also write own httpProvider for check result from server
module.config(['$httpProvider', function ($httpProvider) {
...
I would suggest you to code like this instead of then so whenever there is success, The success part will be invoked.
$http.get('/path/').success(function (data) {
$scope.yourdata = data.data;
//console.log($scope.yourdata);
}).error(function (error){
//error part
});

Angular 1.5 - passing http post response to controller

I am trying to pass an http response from my controller to a service, it works well except for getting the response to go into the controller here is my code below:
For my service
app.factory('ApiService',function($http,Config,$q){
return {
login: function(payload,callBack){
var deferred = $q.defer();
$http({
method:'POST',
url:Config.baseUrl + '/api/login',
data:payload,
headers: {'Content-Type': 'application/json'},
}).then(function successCallback(callBack){
console.log(callBack);
return deferred.resolve(callBack);
}, function errorCallback(callBack){
//deferred.reject(error);
console.log(callBack);
return deferred.reject(callBack);
});
return deferred.promise;
}
}
});
and for the Controller
app.controller('LoginCtrl', function($scope,$position,$rootScope,$state,ApiService) {
$scope.forms = {
'loginForm':''
}
var payload ={
'username':'',
'password':''
}
$scope.userLogin = function(form){
$scope.username = form.username.$modelValue;
$scope.password = form.password.$modelValue;
payload ={
"username":$scope.username,
"password":$scope.password
}
ApiService.login(payload, function(result){
console.log(result);
}
});
Now I don't understand because when I console.log() the response I'm able to see it in the service but doing the same on the controller I'm getting nothing.
No need to make it complex. Simply return promise from factory and use it in controller.
factory:
app.factory('ApiService',function($http,Config,$q) {
return {
login: function(payload) {
return $http({
method:'POST',
url:Config.baseUrl + '/api/login',
data:payload,
headers: {'Content-Type': 'application/json'},
});
}
}
});
in controller :
ApiService.login(payload).then(function(data){
// use response data
}, function(error) {
// handle error
});
You should use it like this:
ApiService.login(payload).then(function(result){
console.log(result);
});
Because you are returning a promise in your service.
Also you don't need that callback parameter, because the then method on the promise is your callback when it finishes and you can access the data your resolve it with.
app.factory('ApiService',function($http,Config,$q){
return {
login: function(payload){
var deferred = $q.defer();
$http({
method:'POST',
url:Config.baseUrl + '/api/login',
data:payload,
headers: {'Content-Type': 'application/json'},
}).then(function (result){
return deferred.resolve(result);
}, function (result){
return deferred.reject(result);
});
return deferred.promise;
}
}
});

Delay $http.get call without affecting angularjs promise

Please note that I already read all the StackOverflow questions that are somewhat related to my questions but none of these really answer my question. Please don't mark this as duplicate without fully understanding my question.
Here's my concern:
I would like to delay angularJS $http.get call without affecting the angular promise. Right now the code below throws a "angular-1.3.15.js:11655 TypeError: Cannot read property 'then' of undefined" in this line:
updatedPromise = promise.then(function(price)
Here's my partial code:
MyAPP.service('FirstService', ['$q','$http', 'Constants', 'SecondService', 'UtilityService', function($q, $http, Constants, SecondService, UtilityService) {
var self = this;
var processFunction = function(AnArray) {
var updatedPromise;
var promises=[];
angular.forEach(AnArray, function(itemObj, index)
{
var totalWorth = "";
if(itemObj.name != "")
{
var promise = SecondService.getPrice(itemObj.name);
updatedPromise = promise.then(function(price){
itemObj.price = price;
return itemObj;
}, function(error){
console.log('[+] Retrieving price has an error: ', error);
});
promises.push(updatedPromise);
}
else
{
console.log("Error!");
}
});
return $q.all(promises);
};
);
MyAPP.service('SecondService', ['$timeout','$http', 'Constants', function($timeout, $http, Constants) {
var self = this;
var URL = "/getPrice";
self.getPrice = function(itemName){
$timeout(function(){
var promise;
promise = $http({
url: URL,
method: 'POST',
data: {_itemName : itemName},
headers: {'Content-Type': 'application/json'}
}).then(function(response) {
return response.data;
}, function(response) {
console.log("Response: " + response.data);
return response.data;
});
return promise;
}, 3500);
console.log("[-]getPrice");
};
}]);
Please note that the processFunction should really return an array of promises because this is needed in other functions.
Your help will be highly appreciated!
Let me know for further questions/clarifications.
Thanks!
$timeout returns a promise, so you can return that, and then return the promise from $http:
self.getPrice = function (itemName) {
return $timeout(3500).then(function () {
return $http({
url: URL,
method: 'POST',
data: { _itemName: itemName },
headers: { 'Content-Type': 'application/json' }
});
}).then(function (response) {
return response.data;
}, function (response) {
console.log("Response: " + response.data);
return response.data;
});
};

How to update controller variable in service angularJS

This is my controller.
sampleApp.controller('SupplierController', ['$scope', '$http', 'SupplierService', function ($scope, $http, SupplierService){
$scope.Suppliers = [];
$scope.getSuppliers = function() {
SupplierService.getSuppliers().then(function(data) {
$scope.Suppliers = data;
});
};
$scope.editSupplier = function(supplier) {
SupplierService.editSupplier(supplier);
editMode = false;
};
$scope.getSuppliers();
}]);
This is my service.
sampleApp.factory('SupplierService', function($http, $q) {
var SupplierService = {};
var SupplierList = [];
SupplierService.getSuppliers = function() {
var Info = {};
Info.Action = "GET";
Info = JSON.stringify (Info);
var req = {
url: SupplierURL,
method: 'POST',
headers: { 'Content-Type': 'application/json'},
data: Info
};
if ( SupplierList.length === 0 )
{
return $http(req).then(function (response) {
SupplierList = response.data
return response.data;
});
}
else
{
var deferred = $q.defer();
deferred.resolve(SupplierList);
return deferred.promise;
}
};
SupplierService.addNewSupplier = function(supplier) {
var Info = {};
Info.Action = "ADD";
Info.SupplierName = supplier.name;
Info.SupplierMobile = supplier.mobile;
Info = JSON.stringify (Info);
var req = {
url: SupplierURL,
method: 'POST',
headers: { 'Content-Type': 'application/json'},
data: Info
};
$http(req)
.success(function(data) {
alert ('Supplier update is successful.');
})
.error(function (data, status, headers, config) {
alert ('Supplier update error.');
});
};
SupplierService.editSupplier = function(supplier) {
var Info = {};
Info.Action = "UPDATE";
Info.SupplierID = supplier.id;
Info.SupplierName = supplier.name;
Info.SupplierMobile = supplier.mobile;
Info = JSON.stringify (Info);
var req = {
url: SupplierURL,
method: 'POST',
headers: { 'Content-Type': 'application/json'},
data: Info
};
$http(req)
.success(function(data) {
alert ('Supplier update is successful.');
})
.error(function (data, status, headers, config) {
alert ('Supplier update error.');
});
};
return SupplierService;
});
What i want is, only when http call for editSupplier is successful then only i want this line to be executed.
editMode = false;
Currently above line is in $scope.editSupplier function. so irrespective of success or failure it is getting called. How to move this line to service??
Any better approach will be highly appreciated.
The easiest way, based on your current setup, would be to return $http(req) (as that is a promise). So the end of editSupplier would say:
return $http(req);
And in your controller, you could do:
SupplierService.editSupplier(supplier).success(function(response) {
editMode = false;
});
You could additionally chain the .error handler if you have something specific to do in the case of an error.
#tandrewnichols stole my initial answer so I'll offer the alternative.:p
Move editMode into the service and use a getter to check the value of editMode.
Also, are you intending to make editMode a global variable in your application?

how to write controller for this service?

myapp.factory('serviceName', function( $http, webStorage){
var factory = {};
var resoureurlBase=some base url;
factory.genericService = function(method, payload, methodName, callbackFn, callbackError, param) {
var httpRequest = null;
if (param && param == true) {
httpRequest = $http({
url: resoureurlBase+methodName,
method: method,
params: payload,
headers: {
'Content-Type': 'application/json'
}
});
} else {
httpRequest = $http({
url: resoureurlBase+methodName,
method: method,
data: payload,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
}
httpRequest.then(function(response) {
if (callbackFn && callbackFn.call) {
callbackFn.call(null, response);
}
},
function(response) {
if (callbackError && callbackError.call) {
callbackError.call(response);
}
});
httpRequest.error(function(data, status, headers, config) {
});
};
return factory;
});
/*
I have written service like above how can i handle in controller
i mean
how to write call back function in controller
how to inject
etc..
*/
Simple DI(dependency injection) it into your controller:-
myapp.controller('myCtrl',['$scope','serviceName',function($scope,serviceName){
// use serviceName to call your factory function
}]);
Ref:- https://docs.angularjs.org/guide/di
You need to call service like
serviceName.genericService(--parmas--).then(function(d){
//success
})
because from service serviceName, you're returning a promise that need to resolved using .then only.
Controller
var mainController = function($scope, serviceName) {
var callbackFn = function() {
console.log('Success');
}
var callbackError = function() {
console.log('Error');
}
var parameter = {
param1: 1
},
method = 'something', payload = 100, methodName = 'something';
serviceName.genericService(method, payload, methodName, callbackFn, callbackError, parameter).then(
//success function
function(data) {
//call after call succeed
},
//error function
function(error) {
//call after call error
});
};
myapp.controller('mainController', ['$scope', 'serviceName', mainController()];
Hope this could help you. Thanks.

Resources