Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

workaround for removing dynamic states #2265

Closed
jtushar53 opened this issue Sep 24, 2015 · 13 comments
Closed

workaround for removing dynamic states #2265

jtushar53 opened this issue Sep 24, 2015 · 13 comments

Comments

@jtushar53
Copy link

creating dynamic states based on roles on login

.config

sfa.sfastates = $stateProvider;

Under Loginj Ctrl
response after login base on user

response.data = {  
  "menu":[  
    {  
      "NAME":"Dashboard",
      "URL":"parts/dashboard.html"
    },
    {  
      "NAME":"Inner Page 1",
      "URL":"parts/innerpage1.html"
    },
    {  
      "NAME":"Inner Page 2",
      "URL":"parts/innerpage2.html"
    }
  ],
  "startuppage":"Dashboard"
};

 var menuObj = {};
       var counter = 0;
       $rootScope.menus = [];
       angular.forEach(response.data.menu, function(item) {
          sfa.sfastates.state('side.'+item.NAME, {
                url: '/'+item.NAME,
                templateUrl: item.URL
              });
          counter++;
       });
       $state.go("side."+response.data.startuppage);

Everything works perfect but, when once login and logout , it wont login again showing state already defined at

sfa.sfastates.state(....)

only way is to login and let the error comes and then refresh page and again login

Can we create above steps from code or can we handle its exception ?

searched everywhere , waiting from last 2-3 months , application is in production with over 4 months of development almost had lost angular just because of this, but somehow convinced my manager to stick to angular:P

anyway to reload angular again when coming on login state
Or empty the stateprovider or check if state exist or not , after logout i can empty everything and start fresh

Any work around , anything

Thank You

@eddiemonge
Copy link
Contributor

Why create "dynamic states"? Why not use permissions instead? like have your response define what areas the user can access and then define all the states and add data: acl: something and in the stateChangeStart: if toState.data.something is user.acl.something (not exact code but gives a general idea)

@jtushar53
Copy link
Author

Implemented your idea previously but it didn't suite our needs,

We have separate access control module only for creating , giving roles to users to access specific pages, assign pages to a user, a department , or a group, or to add pages to the app. So in future if there are any pages needed to be add , we can add it in the specific folder then just give it the path and assign it to the user.

i am writing inline script and using $controllerProvider.register to register controller when partial pages load with theiir controllers.

Like this
app.js

var sfa =  angular.module('xta', [])
.config(function($controllerProvider){
sfa.registerCtrl = $controllerProvider.register;

// Access stateprovider to add states outside config i.e loginCtrl
sfa.sfastates = $stateProvider;
})

dashboard.html (after login)

<script type="text/javascript">
sfa.registerCtrl('DashCtrl', function(){
});
<script>
<div
    ng-controller="DashCtrl">
    <div class="row" >
        <div class="col-md-2 col-xs-2 col-sm-2">
            <i class="fa fa-bars mybar" snap-toggle></i>
        </div>...............

i have around 30-35 pages for 3 users as of now, which may increase in future.

@paulflo150
Copy link

Here is what I ended up doing:

1 Add an init function to the StateProvider:

$StateProvider.$inject = ['$urlRouterProvider', '$urlMatcherFactoryProvider'];
function $StateProvider(   $urlRouterProvider,   $urlMatcherFactory) {
  var root, states = {}, $state, queue = {}, abstractKey = 'abstract';
  this.init = function () {
      states = {};
      queue = {};
  }

2 Add an init function to the UrlRouterProvider:

$UrlRouterProvider.$inject = ['$locationProvider', '$urlMatcherFactoryProvider'];
function $UrlRouterProvider(   $locationProvider,   $urlMatcherFactory) {
  var rules = [], otherwise = null, interceptDeferred = false, listener;

  this.init = function () {
      rules = [];
      otherwise = null;
  }

3 During the config phase as well as upon a logout I call the init below which reinitializes the states and rules:

myapp.provider('router', function ($stateProvider, $urlRouterProvider) {
    this.$get = ['$state', function ($state) {
        return {
            setUpRoutes: function (states) {
                for (var i = 0; i < states.length; i++) {
                    var state = states[i];
                    $stateProvider.state(state.UserRouteName, state.JObject);
                }
                $urlRouterProvider.otherwise('/404');
            }
        }
    }];

    this.init = function () {
        $stateProvider.init();
        $urlRouterProvider.init();

        $stateProvider.state('app', { url: '/app', abstract: true, templateUrl: 'views/main.html' });
        $stateProvider.state('app.organization', { url: '/organization/:id', templateUrl: 'views/organization/organization.html' });
        $stateProvider.state('404', { url: '/404', templateUrl: '404.html' });
        $urlRouterProvider.otherwise('/404');
    };
})

@jtushar53
Copy link
Author

OMG such a simple thing working like a charm

i just added

sfa.sfastates = $stateProvider;
sfa.urlrouter = $urlRouterProvider;
sfa.sfastates.init();
sfa.urlrouter.init();

at the start of config and called init() in logout function thats it.

thank you very much paulflo150 you saved me :).

@ashiquemohammed
Copy link

ashiquemohammed commented Apr 25, 2016

I am facing this same issue , Used $futureStateProvider to build the states , Now I need to remove the states once the user is logged out .@jtushar53 Please tell me how you achieved it ? Thanks

@jtushar53
Copy link
Author

jtushar53 commented May 9, 2016

Hii @32teeths,

follow @paulflo150 steps , you will have to update that piece of code in ui-router.js, BTW i haven't used $futureStateProvider but i've used for loop, have a look at my code above

@paulflo150
Copy link

paulflo150 commented May 9, 2016

@jtushar53, I did run into a problem with this approach and I am hoping 1.0 will allow adding/ removing states on the fly. My use case was that I needed to refresh the states while a user was logged into the application, and reinitializing the router this way cleared all the parent resolves, and the only workaround I could come up with was to refresh the whole state which resulted in the app flickering for a split second. That wasn't the behavior I was looking for, but it will have to do for now.

@christopherthielen
Copy link
Contributor

christopherthielen commented May 9, 2016

I am hoping 1.0 will allow adding/ removing states on the fly

I am hoping that as well.

@ashiquemohammed
Copy link

@jtushar53 Thank you for the response . @paulflo150 How did you refresh the whole state , could you please share the code .

@ashiquemohammed
Copy link

@christopherthielen I see the ui router 1.0 alpha is available right now , but cannot find a doc for removing states , can you please help me out ?

@chlorophant
Copy link

chlorophant commented Aug 25, 2016

I have not been able to employ @paulflo150 's solution. Does anyone have a working plunker? I need to be able to reset/remove all states during runtime (ideally just remove a single state). I am building feature flags for our application, and we need to be able to turn states on and off within the app.

Also, do we know how much of a priority this is for ui-router or an eta?

@christopherthielen
Copy link
Contributor

Will be in 1.0.0-beta.2

@liyanxi
Copy link

liyanxi commented Mar 16, 2017

Each time you refresh the page, will rebuild routing, instead of refreshing the current page
????

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants