0

enter image description hereProblem Question,

I am after restricting URL that can only be navigate to after a process has been finished. More realistic example is of cart and checkout.

Cart (Click on button to checkout) ---- > Checkout (page can only be viewed after button is clicked). Currently if I register my /checkout URL with $stateProvider it can be viewd through URL.

How would I restrict this?

Any Idea on how to do this in Angular and ui-router? Any help is much appreciated

3 Answers 3

2

You can easily restrict URL's by listening for the stateChange event which is fired from rootscope. So lets say you have an orderservice with a property called hasPayed and a state named restricted:

angular.module('tv').run(function($rootScope, OrderService) {
    $rootScope.$on('$stateChangeStart', function (event, next, nextParams, prev, prevParams) {
        if (next.name === 'restricted') {
            if (!OrderService.hasPayed) {
                event.preventDefault();
                $state.go(prev.name, prevParams); //send to previous
                $state.go('other'); //send to some other state
            }
        }
    });
});

https://github.com/angular-ui/ui-router/wiki#state-change-events

Sign up to request clarification or add additional context in comments.

Comments

1

I am using following solution in my projects:

Define a global controller and react to the state change event:

//GLOBAL controller
    angular.module("app.controllers").controller("GlobalController", ["$rootScope", "$state",
            //Check state authentication
            $rootScope.$on("$stateChangeStart", function(event, toState) {
                if (toState.data.public === false && !($rootScope.user)) {
                    event.preventDefault();
                    $state.go("login");
                }
            });
        }
    ]);

In each state, use custom data attribute data.public to prevent unauthorized access:

angular.module("app").config(["$stateProvider", function($stateProvider){
    $stateProvider.state("login", {
        url: "/login",
        templateUrl: "loginTpl.html",
        controller: "LoginCtrl",
        data: {
            public: true
        }
    });
}]);

At a successful login, set $rootScope.user to the corresponding user object!

Edit: For your specific use case, you can use url params (checkout?sender=cart) to solve the problem. In your checkout controller use following:

if($stateParams.sender == "cart")
    //ok
}else{
    $state.go("cart");
}

In the button of your cart:

ui-sref="checkout({sender: 'cart'})"

Comments

0

Let me know if I understand your question correctly.

You have a specific URL that you visit to view your shopping cart. You would like to have it so you can only view the cart if you click a button. This means that if you were to visit the URL where the shopping cart is located that it will not display anything.

If so then the answer is quite simple.

In your shoppingcartController view, you want to set ng-show='cartActive'. This means the cart will only show itself if the variable cartActive is truthy. Now you can have the button set the cartActive variable to true.

If you were to try to visit the endpoint URL without clicking the button, cartActive should be set to false as a default.

Let me know if this answered your question!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.