29

The landing page of my app has two states: home-public, home-logged-in. Now I want to show both states on the same URL, but let the controller and template depend on the user session (is the user logged in or not?).

Is there a way to achieve this?

0

2 Answers 2

51

You could have a base state that controls which state to load, and you could simply have the child stated of that base state not have urls:

.state('home', {
  url: "/home",
  templateUrl: "....",
  controller: function($scope,$state,authSvc) {
     if(authSvc.userIsLoggedIn()){
          $state.go('home.loggedin')
     }else{
          $state.go('home.public')
     }
  }
})


.state('home.public', {
  url: "",
  templateUrl: "....",
  controller: function($scope) {
     ...........
  }
})

.state('home.loggedin', {
  url: "",
  templateUrl: "....",
  controller: function($scope) {
     ...........
  }
})

Now in the controller of your base state (home) you can check if the user is logged in or not, and use $state.go() to load an appropriate state.

EDIT

As promised, a working plunk.

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

9 Comments

This doesn't seem to work. I think it has something to do with the similar URLs. If I comment out one of the sub states, it works.
@jvannistelrooy, I've used this approach before, let me create a plunk.
Thanks, this works! Is it necessary to define empty url's in the substates. For me, it also works without them.
The parent and the childs has the same url, Your trick works just because the parent transact to the childs (home -> home.loggedin). If you transact directly to the child from another state (not 'home') it won't work correctly.. ui-router will call onExit of the child state. I couldn't find a solution to this.. even I can't declare a state as 'unactivable' by hitting the url
@PaoloSanchi you can solve that by making "home" state "abstract: true"
|
0

I am not sure if two states can have the same url. What i can think can be a viable option would be to define a single state

$stateProvider.state('home', {
  templateUrl: function (stateParams){
    // Implement a logic that select what view from the server should be returned for logged in user and otherwise
    //return 'templateurl';
  }
})

I have not tried but it should work.

2 Comments

Thanks, that's what I tried to do, but it seems that I cannot pass my session or user model to myApp.Config, so I cannot build the right logic.
Have you tried templateProvider which is fully injectable. You can try <div ng-include='templateurl'></div in return value. See the example in documentation.

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.