Display custom error page in angular js - angularjs

I can try to make custom error page in angular js
means that when 404 error occurred then display 404.html page
and when 500 error occurred then display 500.html page like so on
so please tell me how can i make this..??

You can handle this with a request interceptor. You didn't provide us with what you use for routing so you'll have to insert your code to route to a 404 page and a 500 page.
The factory will look like this:
angular.module("app").factory('sessionInterceptor', [factory]);
function factory() {
var requestInterceptor = {
response: function(response) {
// Code you want for successful responses here
return response;
},
responseError: function(rejection) {
if (rejection.status === 404) {
// 404 code here
}
return rejection;
}
};
return requestInterceptor;
}
Then you need to add the interceptor in a config block to the $httpProvider:
.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push('sessionInterceptor');
}])
All network requests using $http will now pass through the request interceptor.

Related

Simple interceptor that will fetch all requests and add the jwt token to its authorization header

In my efforts to setup login required to protected pages and reroute to the login page if not authorized, while using Django REST Framework and DRF-JWT, I am trying to go through the following tutorial:
https://www.octobot.io/blog/2016-11-11-json-web-token-jwt-authentication-in-a-djangoangularjs-web-app/
I am not sure what this looks like in step 3 of the front-end section.
// Add a simple interceptor that will fetch all requests and add the jwt token to its authorization header.
Can someone provide an example?
Also, my original post regarding the issues I am having setting this up in general.
Trying to get login required to work when trying to access protected pages
Thanks!
The interceptors are service factories that are registered with the
$httpProvider by adding them to the $httpProvider.interceptors array.
The factory is called and injected with dependencies (if specified)
and returns the interceptor.
The basic idea behind intercepter is that it will be called before each $http request and you could use a service to check if user is logged in and add a token or anything else that needs to be added into the header.You could also add some logic for response for each $http request, like handling the response based on status code.
Here is how you can use it in angular for adding the access token for each http request.
angular.module('myapp')
.run(['$rootScope', '$injector', function($rootScope,$injector) {
$injector.get("$http").defaults.transformRequest = function(data, headersGetter) {
if (sessionService.isLogged()) {
headersGetter()['Authorization'] = "Bearer " + sessionService.getAccessToken();
}
if (data) {
return angular.toJson(data);
}
};
});
Here is how you can use response intercepter:
angular.module('myapp')
.factory('authHttpResponseInterceptor', function($q, $location, sessionService, $http) {
return {
response: function(response) {
//some logic here
return response || $q.when(response);
},
responseError: function(rejection) {
if (rejection.status === 401) {
//some logic here
}
return $q.reject(rejection);
}
}
});

angularjs http interceptor to show error on loaded location path

I have an application for which I created an interceptor to handle token expirations after 15 minute inactivity, it successfully redirects to the login page after a token has expired, but Im not able to show the error after redirecting to the login page.
My question is, how can I show the user the token expired error on the login page, after the interceptor has redirected the app to that page.
Heres my redirector:
app
.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push(function($q, $location, LoopBackAuth) {
return {
responseError: function(rejection) {
if (rejection.status == 401) {
//Now clearing the loopback values from client browser for safe logout...
LoopBackAuth.clearUser();
LoopBackAuth.clearStorage();
$location.path("/login");
}
return $q.reject(rejection);
}
};
})
}])
.config(function(LoopBackResourceProvider) {    
LoopBackResourceProvider.setAuthHeader('X-Access-Token');
})
Finally and thanks to #forrestmid to point me in the right direction this is what I ended up doing.
on the http interceptor just added:
$location.path("/login").search({error: 'invalid_token'});
and then on the controller just had to do:
var queryString = $location.search();
$scope.errors = {};
if (queryString && queryString.error) {
$scope.errors = {
'invalid_token': {
code: 'invalid_token'
}
}
}
now on the template I already have logic to handle the error object so now it works fine :)
Referencing this post in regards to injecting the $state service into an HTTP interceptor:
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push(function($q, $injector, LoopBackAuth) {
return {
responseError: function(rejection) {
if (rejection.status == 401) {
//Now clearing the loopback values from client browser for safe logout...
LoopBackAuth.clearUser();
LoopBackAuth.clearStorage();
$injector.get('$state').go('app.login', {error: 'Token expired.'});
}
return $q.reject(rejection);
}
};
})
}]);
Assuming that you're using ui.router:
app.config(function($stateProvider){
$stateProvider
.state("app",{abstract: true})
.state("app.login", {
url: "/login",
params: {error: ""}
});
});
By default there will be no error when transitioning to the app.login state, but when there is a param error set to whatever, it can display the error. This will be in the $stateParams.error variable on your login page.
Let me know if I botched any of that code since I didn't test it. The line I think you want is the $injector line.

Why my angular interceptor always return 404 code error?

My code:
app.factory('myHttpInterceptor', function ($q) {
return {
responseError: function (response) {
console.log("error111111"+JSON.stringify(response));
if(response.status==403)
console.log("403");
else if(response.status==401)
console.log("401");
else
console.log("404");
return $q.reject(response);
}
};
});
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push('myHttpInterceptor');
}]);
I'd like to handle status code response. But, it always return 404 code in responseError.
I did a simulation with PHP to return me 403 status => http_response_code(403);
In my chrome inspect shows me 403 code error, but when I see the status code of Interceptor shows me 404 . Why?
Ps: My request is being done using angular jsonp.
Any Help?

Angularjs partial not found

I have an angularjs project. I am just wondering, how to show the user a message, if a requested view/partial is not found (HTTP 404). At the moment, angular starts the request and gets a 404 response including the error-html, but the user doesn't see any change to the website.
Add an $http interceptor (scroll down on this page) for 'responseError'
angular.module("app").config(function($provide, $httpProvider) {
// register the interceptor as a service
$provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {
return {
'responseError': function(response) {
if (response.status == 404) {
// user hit a 404 -- you can check response.url to see if it matches
// your template directory and act accordingly
return responseOrNewPromise
}
return $q.reject(rejection);
}
};
});
$httpProvider.interceptors.push('myHttpInterceptor');
});

AngularJS: DRY $http .error()

So I have a bunch of controllers that do $http requests
but in every $http request i have a .error(function(data...){//always the same})
How could I build an.. "abstract class" for $http?
This here would be the always repeating code
.error(function(){
$scope.flashes = {
server: {
type: "danger",
message: "There was a server error processing your request. Please try again later."
}
};
})
I add the same concern few weeks ago and i came up with this solution :
I first created a custom service intercepting every http requests made :
.factory('HttpInterceptor', ['$q', '$rootScope', function($q, $rootScope) {
return {
// On request success
request : function(config) {
// Return the config or wrap it in a promise if blank.
return config || $q.when(config);
},
// On request failure
requestError : function(rejection) {
//console.log(rejection); // Contains the data about the error on the request.
// Return the promise rejection.
return $q.reject(rejection);
},
// On response success
response : function(response) {
//console.log(response); // Contains the data from the response.
// Return the response or promise.
return response || $q.when(response);
},
// On response failure
responseError : function(rejection) {
//console.log(rejection); // Contains the data about the error.
//Check whether the intercept param is set in the config array. If the intercept param is missing or set to true, we display a modal containing the error
if (rejection.config && typeof rejection.config.intercept === 'undefined' || rejection.config.intercept)
{
//emitting an event to draw a modal using angular bootstrap
$rootScope.$emit('errorModal', rejection.data);
}
// Return the promise rejection.
return $q.reject(rejection);
}
};
}]);
I also defined a custom config property 'intercept' that i can add to the $http config object. It is useful when I don't want to apply this behavior on a particular request.
E.g :
var registerResource = $resource('/registration/candidate/register', {}, {query:
{method:'POST', isArray: false, intercept: false }
});
In order the have a flexible solution, it is also important to not forget to do :
return $q.reject(rejection);
So you can still use the error callback on your promise in your controller if you want to combine both ways (interception + manual handling)
Finally, I added this service to my application :
app.config(['$httpProvider', function($httpProvider) {
// Add the interceptor to the $httpProvider to intercept http calls
$httpProvider.interceptors.push('HttpInterceptor');
}]);
I simplified the service but you can also use it for many things. Personally, I also use it to :
Make sure to not fire duplicate http requests (if the user click a lot on a submit button).
Draw an alert at the beginning of an http call and close it at the end to inform the user that is treatment is processing (export of data for instance).
PS: The official documentation mention this interceptor
You could do something like this:
app.service('myHttp', function($http){
return function($scope, httpParameters){
var httpPromise = $http(httpParameters);
httpPromise.error(function(){
$scope.flashes = {
server: {
type: "danger",
message: "There was a server error"
}
}
});
};
});
app.controller('MainCtrl', function($scope, myHttp) {
myHttp($scope, {method: 'GET', url: 'www.google.com'});
});

Resources