AngularJS Error: Unknown provider: $intervalProvider <- $interval <- inputsWatcher <- inputDirective
angularjs, javascript
Solution
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.
Problem
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); } } } }]); ```