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);
}
}
}
Related
I have a login function that works. But, when the user enters an invalid credential, i of course want to display this. But I cant seem to catch the error.
This is my code that works;
function userAccount($resource) {
return {
login: $resource("/Token", null,
{
'loginUser': {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
transformRequest: function (data, headersGetter) {
var str = [];
for (var d in data)
str.push(encodeURIComponent(d) + "=" +
encodeURIComponent(data[d]));
return str.join("&");
}
}
})
}
}
vm.login = function () {
vm.userData.grant_type = "password";
vm.userData.userName = vm.userData.email;
userAccount.login.loginUser(vm.userData,
function (data) {
//login
},
function (response) {
//run this if error (code 400 or similar error)
});
}
});
What do I need to change, to make sure the last bit is run, when to request fails?
EDIT
I found this in the code, and it looks like that is intercepting the error - but how do i get it to, work with my login function, so i can get an error displayed to the user?
.factory('authInterceptor', [
"$q", "$window", "$location", "currentUser", function ($q, $window, $location, currentUser) {
return {
request: function (config) {
if (currentUser.getProfile().token) {
config.headers = config.headers || {};
config.headers.Authorization = 'Bearer ' + currentUser.getProfile().token;
}
return config;
},
response: function(response) {
return response || $q.when(response);
},
responseError: function(rejection) {
// error handler
}
};
}
])
.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push('authInterceptor');
}])
When i remove the last 3 lines, and thereby disabling the interceptor, it works, and the error is caught and showed to the user.
So how to make these work together? :)
You need to return the rejection or error object back to the login user requset object like this
.factory('authInterceptor', [
"$q", "$window", "$location", "currentUser", function ($q, $window, $location, currentUser) {
return {
request: function (config) {
if (currentUser.getProfile().token) {
config.headers = config.headers || {};
config.headers.Authorization = 'Bearer ' + currentUser.getProfile().token;
}
return config;
},
response: function(response) {
return response || $q.when(response);
},
responseError: function(rejection) {
if(ableToREsolve()){
return customRejection
}
return $q.reject(rejection);
}
};
}
])
This in turn will be caught in :
responseError: function(rejection) {
// Show in modal or alert
}
For better understanding I suggest to read on interceptors. Interceptors are of four types:
Request
2.Request Error
3.Response
4.Response Error
In simple words, Interceptors get called before actual
request is passed on to server
response is delivered to client
So in your case error needs to be returned from interceptor in able to be caught by your request object error function.
request
I am building an App with ionic and I want to handle the 500 internal server error which occurs in $http() AJAX call. Is it possible to create any interceptors to handle that?
here is my controller code:
.controller('RegistrationController',function($scope,$http){
$scope.doRegistration = function(){
$http({
method : "POST",
url : BASE_URL,
params : {
//sending the parameters as JSON
}
}).then(function successCallback(response){
if(response.status == 200)
//handling the response sent by server
},function errorCallback()});
};
});
if the user enters some invalid inputs and the server is unable to handle that it throws 500 Internal Server Error. When the AJAX call is made I am showing a spinner and when some server error occurs I should stop the AJAX call and stop the spinner and show some popup to user saying "Encountered server error".
'use strict';
angular.module('myApp').factory('MyService', function ($http, $q) {
var BASE_URL = 'some.url.com';
function register() {
var defer = $q.defer();
$http({method: "POST", url: BASE_URL, params: {}})
.then(function (response) {
defer.resolve(response.data);
})
.catch(function (reason) {
defer.resolve(reason);
});
return defer.promise;
}
return {
register: register
}
}).controller('MyController', function ($scope, MyService) {
MyService.register().then(function (response) {
// success
}).catch(function (reason) {
// err
if (reason.status === 500) {
// do something
$scope.spinner = false;
console.log('Encountered server error');
}
});
});
you can create interceptor as below -
app.factory('testResponseInterceptor', function ($q ,$rootScope,$location) {
return {
response: function (response) {
//correct response
return response;
},
responseError: function (response) {
//error in response
}
};
});
and configure it in your module -
app.config(function ($httpProvider) {
$httpProvider.interceptors.push('testResponseInterceptor');
});
//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');
}
});
}
};
}]);
I'm using CordovaHTTP with Angular and injected the Cordova HTTP into a service. I haven't found many examples on how to implement a POST so below is what I did so far. The issue I'm having is that the post block never reaches the success or error blocks and my debug statements are not getting printed.
Does this look correct?
Calling function:
this.authenticate = function ( code, data, callback ) {
try {
// Build url
var url = o.buildServerUrl(o.loginUrl, code);
RestService.post(url, data, function(response) {
if (response.status === o.HTTP_STATUS_OK) {
...
}
callback(response);
});
}
catch(err) {
var response = o.createServerErrorResponse(o.MSG_SERVER_ERROR);
callback(response);
}
}
Service:
oApp.service( 'RestService', function( cordovaHTTP ) {
this.post = function ( url, data, callback ) {
try {
// Build url
if (o.debug) console.log('Cordova REST: '+url);
cordovaHTTP.post( url, data, {}, function(response) {
if (o.debug) console.log('Rest ok');
// Success
var response = o.processServerResponse(response);
callback(response);
}, function(response) {
if (o.debug) console.log('Response error');
var response = o.processCordovaServerResponse(response);
callback(response);
});
}
catch(err) {
var response = o.createExceptionResponse(err.message);
callback(response);
}
}
});
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();
...