Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS Error: Unknown provider: $intervalProvider <- $interval <- inputsWatcher <- inputDirective

I'm trying to add this solution to my angularjs app to solve the angularjs autocomplete issue. I'm not sure what i'm missing or doing wrong because I'm currently getting the error:

Error: Unknown provider: $intervalProvider <- $interval <- inputsWatcher <- inputDirective

Part of my app.js

// Module for the login page
var myapp = angular.module('myapp', []);

myapp.config(["$routeProvider", "$httpProvider", "$provide", function($routeProvider, $httpProvider, $provide) {

    // Setup the routing
    $routeProvider
        .when('/login', 
            {
                title: 'Login',
                controller: 'LoginController',
                templateUrl: 'partials/login.html'
            })
        .when('/signup', 
            {
                title: 'Signup',
                controller: 'SignupController',
                templateUrl: 'partials/signup.html'
            })
        .otherwise({redirectTo: '/login'});

    // This loads the ajax loading image when necessary
    var $http,
    interceptor = ['$q', '$injector', function ($q, $injector) {
        var error;

        function success(response) {
            // get $http via $injector because of circular dependency problem
            $http = $http || $injector.get('$http');
            if($http.pendingRequests.length < 1) {
                $('#loadingWidget').hide();
                $('#loadingBackdrop').hide();
            }
            return response;
        }

        function error(response) {
            // get $http via $injector because of circular dependency problem
            $http = $http || $injector.get('$http');
            if($http.pendingRequests.length < 1) {
                $('#loadingWidget').hide();
                $('#loadingBackdrop').hide();
            }
            return $q.reject(response);
        }

        return function (promise) {
            $('#loadingWidget').show();
            $('#loadingBackdrop').show();
            return promise.then(success, error);
        }
    }];

    $httpProvider.responseInterceptors.push(interceptor);



    // Due to browsers issue, it's impossible to detect without a timeout any changes of autofilled inputs
    // https://github.com/angular/angular.js/issues/1460
    // https://github.com/angular/angular.js/issues/1460#issuecomment-28662156
    // Could break future Angular releases (if use `compile()` instead of `link())
    // TODO support select
    var inputDecoration = ["$delegate", "inputsWatcher", function($delegate, inputsWatcher) {
        var directive = $delegate[0];
        var link = directive.link;

        function linkDecoration(scope, element, attrs, ngModel){
            var handler;
            // By default model.$viewValue is equals to undefined
            if(attrs.type == "checkbox"){
                inputsWatcher.registerInput(handler = function(){
                    var value = element[0].checked;
                    // By default element is not checked
                    if (value && ngModel.$viewValue !== value) {
                        ngModel.$setViewValue(value);
                    }
                });
            }else if(attrs.type == "radio"){
                inputsWatcher.registerInput(handler = function(){
                    var value = attrs.value;
                    // By default element is not checked
                    if (element[0].checked && ngModel.$viewValue !== value) {
                        ngModel.$setViewValue(value);
                    }
                });
            }else{
                inputsWatcher.registerInput(handler = function(){
                    var value = element.val();
                    // By default value is an empty string
                    if ((ngModel.$viewValue !== undefined || value !== "") && ngModel.$viewValue !== value) {
                        ngModel.$setViewValue(value);
                    }
                });
            }

            scope.$on("$destroy", function(){
                inputsWatcher.unregisterInput(handler);
            });

            // Exec original `link()`
            link.apply(this, [].slice.call(arguments, 0));
        }

        // Decorate `link()` don't work for `inputDirective` (why?)
        /*
         directive.link = linkDecoration;
         */
        // So use `compile()` instead
        directive.compile = function compile(element, attrs, transclude){
            return linkDecoration;
        };
        delete directive.link;

        return $delegate;
    }];

    $provide.decorator("inputDirective", inputDecoration);
    $provide.decorator("textareaDirective", inputDecoration);
    //TODO decorate selectDirective (see binding "change" for `Single()` and `Multiple()`)

}]);

myapp.factory("inputsWatcher", ["$interval", "$rootScope", function($interval, $rootScope){
    var INTERVAL_MS = 500;
    var promise;
    var handlers = [];

    function execHandlers(){
        for(var i = 0, l = handlers.length; i < l; i++){
            handlers[i]();
        }
    }

    return {
        registerInput: function registerInput(handler){
            if(handlers.push(handler) == 1){
                promise = $interval(execHandlers, INTERVAL_MS);
            }
        },
        unregisterInput: function unregisterInput(handler){
            handlers.splice(handlers.indexOf(handler), 1);
            if(handlers.length == 0){
                $interval.cancel(promise);
            }
        }
    }
}]);
like image 395
Catfish Avatar asked Feb 04 '14 16:02

Catfish


1 Answers

The $interval service was added with version 1.2.0-rc.3 (See https://github.com/angular/angular.js/blob/master/CHANGELOG.md#120-rc3-ferocious-twitch-2013-10-14). This error will happen with any version before this.

like image 91
dnc253 Avatar answered Oct 15 '22 20:10

dnc253