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 !

1

2 Answers 2

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.');
    }
  }
});
Sign up to request clarification or add additional context in comments.

1 Comment

Why do you need to add a .hidden class? Why not using ng-show?
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.

1 Comment

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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.