Search code examples
angularjsinternet-explorer-11

AngularJS error [$injector:unpr] Unknown provider: in IE11


I couldn't find help in Google or here either. I'm new to Angular and I'm facing this error only in IE11 and below.

The error I'm getting is this:
console error shown in IE

My IE is in Portuguese so the translate of the first error is: it's not possible to get property of "getAttribute" of undefined or null

this is my app.config.js file

// Checking if an optional module is registered.
// If it's not, register an empty one to prevent errors.
(function(optDeps){
    optDeps.forEach(function(dep){
        try{
            angular.module(dep);
        }catch(e){
            angular.module(dep, []);
        }
    })
})(['ui.carousel', 'ui.mask', 'vAccordion', 'ngAnimate']);

angular

.module('poletto', [
    // Third party
    'smoothScroll',
    'ui.carousel',
    'ui.mask',
    'vAccordion',
    'ngAnimate',
    
    // Components
    'poletto.components',

    // Controllers
    'poletto.controllers',

    // Directives
    'poletto.directives',

    // Factories
    'poletto.factories',

    // Filters
    'poletto.filters',

    // Services
    'poletto.services'
])

.constant('CONSTANTS', {
    BASE_URL: document.currentScript.getAttribute('data-base-url')
})

.config(function($httpProvider){
    $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
})

.config(function($locationProvider){
    if(window.history.pushState){
        $locationProvider.html5Mode({ enabled: true, requireBase: false, rewriteLinks: false });
    }
})

// Extending JQLite with a function that find nodes by className
.run(function(){
    angular.element.prototype.findBySelector = function(selector){
        var matches = [];
        
        for(key in this){
            // Pushing only HTMLElement's
            if(this[key].nodeType){
                // NodeList to array
                var results = Array.prototype.slice.call(this[key].querySelectorAll(selector));

                matches.push.apply(matches, results);
            }
        }

        return angular.element(matches);
    };
})

I've searched google and tried some solutions such as:

  • add <meta http-equiv="X-UA-Compatible" content="IE=11" />

  • wrap all my declarations in:

(function (angular) {
    "use strict";
    //code
}(window.angular));
  • add this in html tag:
<html lang="pt-br" xmlns:ng="http://angularjs.org">
  • Also I couldn't find any angular polyfills neither src/ folder, which I saw in a similar question with angular 2.

I don't know which file I should put here, so if you need some more info, you can ask me and I update the question.


Solution

  • Unfortunately document.currentScript is not supported on IE and can't be polyfilled so it can't done that way. Perhaps, you can embed the base url somewhere else or maybe add an id to your script and retrieve it in old school javascript.

    <script id="main" data-base-url="https://my-api.com"></script>
    

    And then retrieve it like this:

    var currentScript = document.getElementById('main');
    

    In your CONSTANTS provider you can do something like this:

    .constant('CONSTANTS', {
        BASE_URL: document.getElementById('main').getAttribute('data-base-url')
    })