render 404 page without redirecting in angular js
Asked Answered
T

2

4

I am using ui.router & ngResource with AngularJS, & my question is :

How do I RENDER 404 without redirecting to it e.g A user typed http://www.example.com/wrong-page-name , he should just be shown the 404 page, and the URL shouldn't change.

Currently this is how I did it but it redirects

    angular.module('app')
   .run(['$rootScope', '$state', function($rootScope, $state) {

            $rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error) {
                if(error.status === 404) {
                    $state.go('innerPages.page', {slug:"not-found"});
                }
            });
    })
    .config(['$stateProvider','$urlRouterProvider', function($stateProvider, $urlRouterProvider) {

            $stateProvider.state('innerPages.page', {
                url: ':slug',
                views : {
                    'content@':{
                        templateUrl : '...',
                        controller : 'pageController'
                    },
                    'pageHeader@' : {
                        templateUrl : "...",
                        controller : 'pageController'
                    }
                },
                resolve:{
                    page: ['pageService', '$stateParams', function (pageService, $stateParams) {
                        return pageService.get({slug:$stateParams.slug}).$promise;
                    }]
                }
            });

        }]);

Thanks for Help !

Trivial answered 27/1, 2015 at 13:17 Comment(1)
What about this: How not to change url when show 404 error page with ui-routerBratton
G
2

Why don't you just show the 404 template?

<any ng-view ng-class="{'hidden': notFound}"></any>
<div class="not-found-template hidden" ng-class="{'hidden': !notFound}">
  <h2>Not Found!</h2>
</div>

And for the css:

.hidden
{
  display: none !important;
}

And add a service for error handling (optional)

 angular.module('app').service('Errors', function ($rootScope) {
  this.handle = function (error, status) {
    // not found
    switch (status) {
      case 404:
        alert('Sorry! the page was not found.');
        // This is the required line for showing 404 template
        $rootScope.notFound = true;
        break;
      case 500:
        alert('Sorry! Error connecting to server.');
        break;
      case 403:
        $location.path('/login');
        break;
      default:
        alert('Sorry! Error connecting to server.');
    }
  }
});
Ginseng answered 9/2, 2015 at 12:40 Comment(1)
Why do you need to add a .hidden class? Why not using ng-show?Revell
G
0

I like to add a recommended and more structured answer:

The $httpInterceptor factory documented here (see Interceptors paragraph) is used:

For purposes of global error handling, authentication, or any kind of synchronous or asynchronous pre-processing of request or postprocessing of responses

in all of HTTP requests through your app.
Change the responseError method like:

'responseError': function (error) {


  //hide any showing loader spinners
  loader.hide();


  // handle errors by type
  var status = error.status;
  switch (status) {


    // here you can show 404 templates and go more further
    case 404:
      $rootScope.flags.errorCode = 404;
      break;


    // here I check if error has messages or it's an internal server error
    case 500:
      try {
        if (!error.data.success && typeof error.data.data.message != 'undefined') {
          Notification.error(error.data.message);
        } else {
          $rootScope.flags.errorCode = 500;
        }
      } catch (e) {
        $rootScope.flags.errorCode = 500;
      }
      break;


    // authenticating for actions that un-authenticated uses can not do, like staring or commenting
    case 401:
      Popup.show('login');
      break;


    // showing notification for any other error types
    default:
      Notification.error('Sorry! Error connecting to server.');
  }
  return $q.reject(error);
}

about the above code:

  1. Loader is my custom service to show loader-spinner and may have overlay, onElement and any other required types.
  2. Notification is also a custom service for notifying client about the result of requests.
  3. Any error templates may be controlled using flags object pinned to $rootScope.
Ginseng answered 16/7, 2015 at 14:17 Comment(1)
This is not a good solution. You don't want to redirect to a 404 page on every 404 response you get from the server. There are cases in which just showing an error message is enough, depending on the resource that's not found.Revell

© 2022 - 2024 — McMap. All rights reserved.