Pasan Ratnayake
Pasan Ratnayake

Reputation: 495

How to catch the invalid URL?

I am building a simple HTML site using Angular JS ui-router.

I have built a custom 404 page ('www.mysite/#/error/404'), to which the user is redirected if the user types a url like 'www.mysite/#/invalidUrl'. This functionality was achieved by the following code snippet:

$urlRouterProvider
            .when('', '/')
            .when('/home', '/')
            .otherwise('/error/404');

And the following state snippet:

$stateProvider.state('404', {
            parent: 'app',
            url: '^/error/404',
            views: {
                'errorContent@main': {
                    controller: 'error404Controller',
                    templateUrl: 'js/general/templates/error404.html'
                }
            }
        });

I am trying to capture the invalid URL requested by the user to be displayed to the user like below.

The URL you requested cannot be found
Request: www.mysite.com/#/invalidUrl

I have tried listening to '$stateNotFound' event, which only seems to be firing when a specific invalid state is requested. I've also tried to listening to events '$stateChangeStart', '$locationChangeStart', and '$locationChangeSuccess' but couldn't find a way to achieve this functionality.

Is this possible? Please, share your thoughts - thank you

Upvotes: 6

Views: 3256

Answers (1)

Pasan Ratnayake
Pasan Ratnayake

Reputation: 495

Awesome! Thank you Radim Köhler. I don't know how I didn't land on that thread when I searched but that helped me get the answer.

I changed the answer in that thread to fit my scenario which I am going to leave below for reference to any other users.

$stateProvider.state('404', {
            parent: 'app',
            url: '^/error/404',
            views: {
                'errorContent@main': {
                    controller: 'error404Controller',
                    templateUrl: 'js/general/templates/error404.html'
                }
            }
        });

        $urlRouterProvider
            .when('', '/')
            .when('/home', '/')
            .otherwise(function ($injector, $location) {
                var state = $injector.get('$state');
                state.go('404', { url: $location.path() }, { location: true });
        });

So the magic change was the function defined for 'otherwise' option. I didn't change the URL of the 'error' state. Instead, I used the 'state.go' to activate state '404' and passed the location path as the state parameter.

Setting location=true will take you to the URL of the state, and location=false will not. Whichever way you prefer the invalid URL can be accessed easily now.

Upvotes: 6

Related Questions