1

I have created a web application with angularJS and PHP for the back-end. I encountered a strange error which occasionally occurs in Internet Explorer. Chrome has no problems. I get an InvalidStateError on the <main> HTML element of my application. When the error occurs, the app crashes. I can't reproduce it when I only open the application on 1 device. When I open the application on multiple devices, the error occurs occasionally. The application contains a login where, for testing, the user logs in with the same username. I have tried to use a random username for login, so users won't login with the same username. Did not resolve the problem. I have no idea what the problem is. Maybe a request which fails, maybe a server configuration, maybe a file which can't be loaded. I have no idea what triggers the error. Can you guys give any directions where to search for this kind of error?

See the error below:

InvalidStateError <main class="ng-scope" ng-if="!app.isMobile" data-ui-view="main">
{
  [functions]: ,
  __proto__: {
     [functions]: ,
     __proto__: { },
     ABORT_ERR: 20,
     code: <Permission denied>,
     constructor: { },
     DATA_CLONE_ERR: 25,
     DOMSTRING_SIZE_ERR: 2,
     HIERARCHY_REQUEST_ERR: 3,
     INDEX_SIZE_ERR: 1,
     INUSE_ATTRIBUTE_ERR: 10,
     INVALID_ACCESS_ERR: 15,
     INVALID_CHARACTER_ERR: 5,
     INVALID_MODIFICATION_ERR: 13,
     INVALID_NODE_TYPE_ERR: 24,
     INVALID_STATE_ERR: 11,
     message: <Permission denied>,
     name: <Permission denied>,
     NAMESPACE_ERR: 14,
     NETWORK_ERR: 19,
     NO_DATA_ALLOWED_ERR: 6,
     NO_MODIFICATION_ALLOWED_ERR: 7,
     NOT_FOUND_ERR: 8,
     NOT_SUPPORTED_ERR: 9,
     PARSE_ERR: 81,
     QUOTA_EXCEEDED_ERR: 22,
     SECURITY_ERR: 18,
     SERIALIZE_ERR: 82,
     SYNTAX_ERR: 12,
     TIMEOUT_ERR: 23,
     TYPE_MISMATCH_ERR: 17,
     URL_MISMATCH_ERR: 21,
     VALIDATION_ERR: 16,
     WRONG_DOCUMENT_ERR: 4
  },
  ABORT_ERR: 20,
  code: 11,
  constructor: { },
  DATA_CLONE_ERR: 25,
  DOMSTRING_SIZE_ERR: 2,
  HIERARCHY_REQUEST_ERR: 3,
  INDEX_SIZE_ERR: 1,
  INUSE_ATTRIBUTE_ERR: 10,
  INVALID_ACCESS_ERR: 15,
  INVALID_CHARACTER_ERR: 5,
  INVALID_MODIFICATION_ERR: 13,
  INVALID_NODE_TYPE_ERR: 24,
  INVALID_STATE_ERR: 11,
  message: "InvalidStateError",
  name: "InvalidStateError",
  NAMESPACE_ERR: 14,
  NETWORK_ERR: 19,
  NO_DATA_ALLOWED_ERR: 6,
  NO_MODIFICATION_ALLOWED_ERR: 7,
  NOT_FOUND_ERR: 8,
  NOT_SUPPORTED_ERR: 9,
  PARSE_ERR: 81,
  QUOTA_EXCEEDED_ERR: 22,
  SECURITY_ERR: 18,
  SERIALIZE_ERR: 82,
  SYNTAX_ERR: 12,
  TIMEOUT_ERR: 23,
  TYPE_MISMATCH_ERR: 17,
  URL_MISMATCH_ERR: 21,
  VALIDATION_ERR: 16,
  WRONG_DOCUMENT_ERR: 4
}
"<main class="ng-scope" ng-if="!app.isMobile" data-ui-view="main">"

And here is the class where I set the UI view:

(function(){
'use strict';

/* @mindPreloads */
var image_structure = ['spritesheets/sheet_faq.png','spritesheets/sheet_global.png','spritesheets/sheet_globe.png','spritesheets/sheet_mission_select.png','spritesheets/sheet_mockups.jpg','spritesheets/sheet_progress.png','spritesheets/sheet_quiz.png','spritesheets/sheet_start_screen.png'];

angular
    .module('App')
    .config(Routes)
    .run(Routing);

Routes.$inject = ['$stateProvider', '$urlRouterProvider'];

function Routes($stateProvider, $urlRouterProvider)
{
    var defaultRoute = '/error/notfound';

    $urlRouterProvider
        .when('', '/login')
        .when('/', '/login')
        .otherwise(defaultRoute);

    $stateProvider
        .state('app', {
            'abstract': true,
            resolve: {
                authStatus: [
                    'AuthService',
                    function(authService) { return authService.authorise(); }
                ],
                preload: [
                    'Preloader',
                    function(Preloader) { return Preloader.loadImages(image_structure, 'sheet_faq', 'sheet_global', 'sheet_globe', 'sheet_mission_select', 'sheet_mockups', 'sheet_progress', 'sheet_start_screen'); }
                ]
            }
        })
        .state('notfound', createRoute('/error/notfound', '/error/notfound.html'))
        .state('denied', createRoute('/error/denied', '/error/denied.html'))

        // Authenticated routes
        .state('login' , createRoute('/login' , '/login/login.html', 'Login' , 'app'    , null))
        .state('logout', createRoute('/logout', ''                 , 'LogoutController', 'app', ['basic']))
        .state('home'  , createRoute('/home'  , '/home/home.html'  , 'Home'  , 'app', ['basic'], HomeRes.resolve))
        .state('quiz'  , createRoute('/quiz'  , '/quiz/quiz.html'  , 'Quiz'  , 'app', ['basic'], { preloadQuiz: ['Preloader', 'Communication', function(Preloader, Communication) { return Preloader.loadImages(image_structure, 'sheet_quiz') }]}))
        .state('debug' , createRoute('/debug' , '/debug/debug.html', 'Quiz'  , 'app', ['basic']))
        ;

}

Routing.$inject = ['$rootScope', 'HomeService', 'DebugService', 'DebuglistService', 'QuizService', '$location', 'Preloader'];

/* @ngInject */
function Routing($rootScope, homeS, debugS, debuglistS, quizS, $location, preloader)
{
    $rootScope.$on('$stateChangeStart', function(event, toState) {
        if(toState.name === "debug") {
            quizS.setMaxQuestionNumber(5);
            IN_DEBUG_QUIZ = true;
            debugS.setPages(debuglistS.getDebugList());
            quizS.reset();
            $location.path('/debug');
        }
    });

    $rootScope.$on('$routeChangeStart',   preloader.setResolveState(true,  true));
    $rootScope.$on('$routeChangeSuccess', preloader.setResolveState(false, true));
    $rootScope.$on('$routeChangeError',   preloader.setResolveState(false, true));
    $rootScope.$on('$stateChangeStart',   preloader.setResolveState(true,  false));
    $rootScope.$on('$stateChangeSuccess', preloader.setResolveState(false, true));
    $rootScope.$on('$stateChangeError',   preloader.setResolveState(false, true));
}

/**
 * Creates a new route
 * @todo   Move this code to a Provider so all modules can use it.
 *
 * @param  {string} url         Url the route should listen to
 * @param  {string} template    Path to template to display (without 'app') in the main view
 * @param  {string} controller  Controller to use (as 'vm')
 * @param  {string} parent      Parent route
 * @param  {array} permissions  Which permissions are required
 * @param  {object} resolve     Items to resolve
 * @return {object}             A route object
 */
function createRoute(url, template, controller, parent, permissions, resolve)
{
    var route = {data: {permissions: []}};
    if (template) {
        route.views  = {'main@': {templateUrl: 'app' + template}};
        if (controller) {
            route.views['main@'].controller   = controller;
            route.views['main@'].controllerAs = 'vm';
        }
    }
    if (parent)      { route.parent           = parent; }
    if (url)         { route.url              = url; }
    if (permissions) { route.data.permissions = permissions; }
    if (resolve)     { route.resolve          = resolve; }
    return route;
}
})();
Kevin
  • 91
  • 1
  • 1
  • 6

2 Answers2

0

The HTML5 main tag is not supported by Internet Explorer 11(See http://caniuse.com/#search=main). To make it work, I think you will need this solution: https://stackoverflow.com/a/35820454/3237604.

  • Thanks for trying to find the problem! It did not solve my error, but it is good to know it is not fully supported. – Kevin Jul 31 '17 at 12:42
0

Okay, so I found the problem! Apparently I was trying to play a sound which was not loaded.

First my code was:

function playButtonPressSound()
{
    click_audio.pause();
    click_audio.currentTime = 0;
    click_audio.play();
}

Now my code is as follows:

function playButtonPressSound()
{
    if(!isNaN(click_audio.duration)) {
        click_audio.pause();
        click_audio.currentTime = 0;
        click_audio.play();
    }
}

I have wrapped a check around the code block to check if the duration is set of the sound. This will return a number if the sound is set and return NaN if the sound is not set.

Credits go to this post: audio.currentTime invalidStateError IE11, JS, HTML5

Kevin
  • 91
  • 1
  • 1
  • 6