javascript - angularjs infdig error when change state on ui-router(with video) - Stack Overflow

New Edit: the authservice that checks the login:'use strict';angular.module('MainApp.l

New Edit: the authservice that checks the login:

'use strict';

angular.module('MainApp.login.services', [])
    .factory('authService', ['AUTH_ENDPOINT', 'LOGOUT_ENDPOINT', '$http', '$cookieStore', function (AUTH_ENDPOINT, LOGOUT_ENDPOINT, $http, $cookieStore) {
        var auth = {};
        auth.login = function (username, password) {
            return $http.post(AUTH_ENDPOINT, {username: username, password: password})
                .then(function (response, status) {
                    auth.user = response.data;
                    $cookieStore.put('user', auth.user);
                    return auth.user;
                });
        };
        auth.logout = function () {
            return $http.post(LOGOUT_ENDPOINT).then(function (response) {
                auth.user = undefined;
                $cookieStore.remove('user');
                $cookieStore.remove('event');
            });
        };
        return auth;
    }])
    .value('AUTH_ENDPOINT', '.php')
    .value('LOGOUT_ENDPOINT', '.php');  

Updated:
Unfortunatelly this is a part of a whole web-application , so i cant upload it on jsfiddle. I made a youtube video where i show exactly the error while i debug the application. From minute 1:30 starts the problem.Feel free to examine the video
below is the app.js of my angular application.

Could the $watch(es) that i have into the templates ,create the error?

Youtube, after 1:30 starts the error : ;feature=youtu.be

When first load the site , the login screen loads and asks for the credentials.

If the user login it redirects to the part4 page(from inside the login controller) , so far so good!

The problem is whenever i open a new tab on the browser , try to load the website:

  1. It should see that the user is already loged in and redirect him on the part4 page.

  2. instead of this , as i see on the debug of the browser , it goes to the resolve:login

  3. Then it goes up inside $rootScope.$on('$stateChangeError', and to the go.state(part4)

  4. Then it goes to the resolve of part4 and then it goes to the resolve of the login and again to the $statechangeerror function

5.And finally i get the error :Error: [$rootScope:infdig] .4.8/$rootScope/infdig?p0=10&p1=%5B%5D but the strange is that it finally redirects to the part4 page, but with that error!!

Can anyone help me please.

'use strict';

var app = angular.module('MainApp', ['mApp',
    'MainApp.loginModule',
    'MainApp.part4Module',
    'MainApp.part5Module',
    'MainApp.eventModule',
    'ui.router', 'ui.router.tabs', 'ngCookies']);

angular.module('MainApp')
    .run(['$rootScope', '$state', '$cookieStore', 'authService', function ($rootScope, $state, $cookieStore, authService) {
        $rootScope.$on('$stateChangeError', function (event, toState, toParams, fromState, fromParams, error) {
            if (error.unAuthorized) {
                $state.go('login');
            }
            else if (error.authorized) {
                $state.go('part4');
            }
        });

        authService.user = $cookieStore.get('user');
    }])
    .config(function ($stateProvider, $urlRouterProvider, $locationProvider) { //$stateProvider & $urlRouterProvider are from ui.router module
        $stateProvider
            .state('floorplan', {
                url: '/floorplan/:activeEventId/:activeHallId/:activeHallVariant',
                controller: 'ParticipantsCtrl',
                templateUrl: '/assets/modules/part1/part1.html',
                resolve: {
                    user: ['authService', '$q', function (authService, $q) {
                        return authService.user || $q.reject({unAuthorized: true});
                    }]
                }
            })
            .state('event', {
                url: '/event/:activeEventId',
                templateUrl: 'assets/modules/event/eventPartial.html',
                controller: 'eventctrl',
                resolve: {
                    user: ['authService', '$q', function (authService, $q) {
                        return authService.user || $q.reject({unAuthorized: true});
                    }]
                }
            })
            .state('part4', {
                url: '/part4',
                resolve: {
                    user: ['authService', '$q', function (authService, $q) {
                        return authService.user || $q.reject({unAuthorized: true});
                    }]
                },
                controller: 'part4ctrl',
                templateUrl: '/assets/modules/part4/part4Partial.html'
            })
            .state('login', {
                url: '/login',
                controller: 'LoginCtrl',
                templateUrl: '/assets/modules/login/login.html',
                resolve: {
                    user: ['authService', '$q', function (authService, $q) {
                        if (authService.user) {   
                         return $q.reject({authorized: true});
                        }
                    }]
                }
            });
        $urlRouterProvider.otherwise('login');
    });

I uploaded a video on youtube , describing and showing the error: youtube: ;feature=youtu.be

New Edit: the authservice that checks the login:

'use strict';

angular.module('MainApp.login.services', [])
    .factory('authService', ['AUTH_ENDPOINT', 'LOGOUT_ENDPOINT', '$http', '$cookieStore', function (AUTH_ENDPOINT, LOGOUT_ENDPOINT, $http, $cookieStore) {
        var auth = {};
        auth.login = function (username, password) {
            return $http.post(AUTH_ENDPOINT, {username: username, password: password})
                .then(function (response, status) {
                    auth.user = response.data;
                    $cookieStore.put('user', auth.user);
                    return auth.user;
                });
        };
        auth.logout = function () {
            return $http.post(LOGOUT_ENDPOINT).then(function (response) {
                auth.user = undefined;
                $cookieStore.remove('user');
                $cookieStore.remove('event');
            });
        };
        return auth;
    }])
    .value('AUTH_ENDPOINT', 'http://www.mydomain.gr/assets/modules/login/dal/login.php')
    .value('LOGOUT_ENDPOINT', 'http://www.mydomain.gr/assets/modules/login/dal/logout.php');  

Updated:
Unfortunatelly this is a part of a whole web-application , so i cant upload it on jsfiddle. I made a youtube video where i show exactly the error while i debug the application. From minute 1:30 starts the problem.Feel free to examine the video
below is the app.js of my angular application.

Could the $watch(es) that i have into the templates ,create the error?

Youtube, after 1:30 starts the error : https://www.youtube./watch?v=3Cc2--BkdQ4&feature=youtu.be

When first load the site , the login screen loads and asks for the credentials.

If the user login it redirects to the part4 page(from inside the login controller) , so far so good!

The problem is whenever i open a new tab on the browser , try to load the website:

  1. It should see that the user is already loged in and redirect him on the part4 page.

  2. instead of this , as i see on the debug of the browser , it goes to the resolve:login

  3. Then it goes up inside $rootScope.$on('$stateChangeError', and to the go.state(part4)

  4. Then it goes to the resolve of part4 and then it goes to the resolve of the login and again to the $statechangeerror function

5.And finally i get the error :Error: [$rootScope:infdig] http://errors.angularjs/1.4.8/$rootScope/infdig?p0=10&p1=%5B%5D but the strange is that it finally redirects to the part4 page, but with that error!!

Can anyone help me please.

'use strict';

var app = angular.module('MainApp', ['mApp',
    'MainApp.loginModule',
    'MainApp.part4Module',
    'MainApp.part5Module',
    'MainApp.eventModule',
    'ui.router', 'ui.router.tabs', 'ngCookies']);

angular.module('MainApp')
    .run(['$rootScope', '$state', '$cookieStore', 'authService', function ($rootScope, $state, $cookieStore, authService) {
        $rootScope.$on('$stateChangeError', function (event, toState, toParams, fromState, fromParams, error) {
            if (error.unAuthorized) {
                $state.go('login');
            }
            else if (error.authorized) {
                $state.go('part4');
            }
        });

        authService.user = $cookieStore.get('user');
    }])
    .config(function ($stateProvider, $urlRouterProvider, $locationProvider) { //$stateProvider & $urlRouterProvider are from ui.router module
        $stateProvider
            .state('floorplan', {
                url: '/floorplan/:activeEventId/:activeHallId/:activeHallVariant',
                controller: 'ParticipantsCtrl',
                templateUrl: '/assets/modules/part1/part1.html',
                resolve: {
                    user: ['authService', '$q', function (authService, $q) {
                        return authService.user || $q.reject({unAuthorized: true});
                    }]
                }
            })
            .state('event', {
                url: '/event/:activeEventId',
                templateUrl: 'assets/modules/event/eventPartial.html',
                controller: 'eventctrl',
                resolve: {
                    user: ['authService', '$q', function (authService, $q) {
                        return authService.user || $q.reject({unAuthorized: true});
                    }]
                }
            })
            .state('part4', {
                url: '/part4',
                resolve: {
                    user: ['authService', '$q', function (authService, $q) {
                        return authService.user || $q.reject({unAuthorized: true});
                    }]
                },
                controller: 'part4ctrl',
                templateUrl: '/assets/modules/part4/part4Partial.html'
            })
            .state('login', {
                url: '/login',
                controller: 'LoginCtrl',
                templateUrl: '/assets/modules/login/login.html',
                resolve: {
                    user: ['authService', '$q', function (authService, $q) {
                        if (authService.user) {   
                         return $q.reject({authorized: true});
                        }
                    }]
                }
            });
        $urlRouterProvider.otherwise('login');
    });

I uploaded a video on youtube , describing and showing the error: youtube: https://www.youtube./watch?v=3Cc2--BkdQ4&feature=youtu.be

Share Improve this question edited Mar 8, 2016 at 19:12 Matt 75.3k26 gold badges156 silver badges180 bronze badges asked Feb 25, 2016 at 21:15 Theo ItzarisTheo Itzaris 4,6666 gold badges44 silver badges75 bronze badges 18
  • I'm a bit confused by your app.js. I'm fairly sure it should be app.run... not angular.module('MainApp').run – LJ.Wizard Commented Feb 25, 2016 at 21:21
  • @LJ.Wizard using angular.module('MainApp') is better practice. Doesn't depend on setting a global variable – charlietfl Commented Feb 25, 2016 at 21:23
  • Hard to help without knowing how authorization works – charlietfl Commented Feb 25, 2016 at 21:25
  • @charlietfl I see. Thanks. – LJ.Wizard Commented Feb 25, 2016 at 21:42
  • You're getting yourself into an infinite loop.. could you get an error.authorized when you get routed to the part4 state? – Brian Baker Commented Feb 26, 2016 at 5:15
 |  Show 13 more ments

3 Answers 3

Reset to default 3 +25

I think the state is resolved first because you inject $state in your app.run.

Which lead to try to resolve the part4 state's resolve with undefined user, then the event is thrown and will be resolved on the next digest cycle, so the use is initialized before you get redirecit to login page, which will redirect you to part4.

Try to separate in two angular.run, the 1st that will run the init of the authService without injectingt $state. The 2nd that will inject the $state to init the$stateCHangeError listener (just defining the 1st one before the 2nd one).

If it's not enough : split your module : the one containing the authService in a module 'A' with the dedicated angular.module('A').run, the 2nd in a module 'B' with a dependency toward 'A' with the angular.module('B').run for the $stateChangeError

Can you try this inverted?

.run(['$rootScope', '$state', '$cookieStore', 'authService', function ($rootScope, $state, $cookieStore, authService) {
    $rootScope.$on('$stateChangeStart', function (...) {
    authService.user = $cookieStore.get('user');
                if (authService.user) {
                    $state.go('part4');
                }
                else if (!authService.user) {
                    $state.go('login');
                }
            });
}

This will skip the to and fro to the $q within your resolve in each route's declaration. Second, this will also resolve you/r checking user all the time within resolve of each route. In .config() set authService.user = $cookieStore.get('user'); somewhere. Should resolve your issue.

Everything seems ok.

After many hours and many breakpoints i realized that the problem was not caused by any $watch(), i have many $watch on my controllers.

It is just a state problem, as you can see on my question , i didnt have '/' state, and that caused the infinite loop ,because:

  1. when i delete the extension part of the url , i have : www.mydomain./ , then the $stateProvider searches my available 'states' but couldnt find '/' state, so it redirects to 'login' state.
  2. Into 'login' state i check if user==true and reject error.
  3. Then , $rootScope.$on('$stateChangeError'){..} executes and i call state.go('part4') , it resolves state 'part4' and again it goes to state 'login' resolve ,and again the same until the maximum number of allowed iterations of the $digest cycle reached.

How i solved it

I dont know if it is the best way but i added a '/' state on app.js, and it works as expected:

.state('/', {
                url: '/',
                controller: 'LoginCtrl',
                templateUrl: '/assets/modules/login/login.html',
                resolve: {
                    user: ['authService', '$q', function (authService, $q) {
                        if (authService.user) {
                            return $q.reject({authorized: true, user: authService.user});
                        }
                    }]
                }
            });

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745095296a4610941.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信