Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unknown provider: ngModelProvider

I am trying to inject ngModel in an Angular directive and I get this error:

Error: [$injector:unpr] Unknown provider: ngModelProvider <- ngModel
http://errors.angularjs.org/1.2.18/$injector/unpr?p0=ngModelProvider%20%3C-%20ngModel
    at http://localhost:2013/Scripts/angular.js:78:12
    at http://localhost:2013/Scripts/angular.js:3741:19
    at Object.getService [as get] (http://localhost:2013/Scripts/angular.js:3869:39)
    at http://localhost:2013/Scripts/angular.js:3746:45
    at getService (http://localhost:2013/Scripts/angular.js:3869:39)
    at invoke (http://localhost:2013/Scripts/angular.js:3896:13)
    at Object.instantiate (http://localhost:2013/Scripts/angular.js:3917:23)
    at $get (http://localhost:2013/Scripts/angular.js:7201:28)
    at http://localhost:2013/Scripts/angular.js:6592:34
    at forEach (http://localhost:2013/Scripts/angular.js:327:20) angular.js:9937
(anonymous function) angular.js:9937
$get angular.js:7283
$get.Scope.$digest angular.js:12414
$get.Scope.$apply angular.js:12660
done angular.js:8272
completeRequest angular.js:8477
xhr.onreadystatechange

Here is my directive:

module.directive("myDatePicker", function () {
    return {
        restrict: "A",
        template: '<p class="input-group" title="{{title}}">' +
                            '<input type="text" class="form-control" data-datepicker-popup="{{dateFormat}}" ng-model="selectedDate" data-is-open="isOpen" data-datepicker-options="dateOptions" ng-required="true" data-close-text="{{closeText}}" />' +
                            '<span class="input-group-btn">' +
                                '<button type="button" class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>' +
                            '</span>' +
                        '</p>',
        replace: true,
        require: '?ngModel',
        //priority: 0,
        scope: {
            title: "@",
            selectedDate: "=ngModel",
            onChange: "&",
            dateFormat: "="
        },
        compile: function (tElement, tAttrs, transclude) {
            // Correct ngModel for isolate scope
            if (tAttrs.ngModel) {
                tAttrs.$set('selectedDate', tAttrs.ngModel, false);
                tAttrs.$set('ngModel', 'selectedDate', false);
            }

            return {
                post: function (scope, iElement, iAttrs, controller) {
                    // Render
                    return controller.$render = function () {
                        if (!controller.$viewValue) {
                            return;
                        }
                        angular.extend(scope, controller.$viewValue);
                    };
                }
            };
        },
        priority: 100,
        link: function (scope, elem, attr) {
        },
        controller: function ($scope, global, ngModel) {
            $scope.isOpen = false;
            $scope.closeText = 'Close';
            $scope.dateOptions = {};

            $scope.open = function ($event) {
                $event.preventDefault();
                $event.stopPropagation();
                $scope.isOpen = true;
            };

            $scope.$watch(function () {
                return $scope.selectedDate;
            },
                function (newValue, oldValue) {
                    ngModel.$setValidity('required', newValue == true);
                    $scope.onChange({ newDate: newValue, oldDate: oldValue });
                }, true);
        }
    };
});

And here is my HTML:

                    <input data-my-date-picker
                           id="EventDatePicker" data-name="EventDatePicker"
                           data-date-format="dateFormat"
                            ng-model="EventDetails.Date"
                           ng-required="true"
                           data-title="Date" />

Why can't it be resolved? I have tried doing this:

module.directive("myDatePicker", ['ngModel', function () {

...but it didn't help.

I have also tried removing priority and it didn't help either.

Is it something related to the order that directives get loaded?

What am I missing here?

Any ideas?


Finally I did this, according to sma's suggestion:

        require: ['^ngModel'/*, '^isDate'*/],
        scope: {
            title: "@?",
            name: "@?"
        },
        link: function (scope, elem, attr, ngModel/*, isDate*/) {
        ...

This kind of seems to work.

I am not sure why I cannot inject this in the controller. :(

There must be a way, but I haven't found it yet...

But for some strange reason, directives like the isDate above still are not injected (although they are defined before the current directive).

This is confusing.

like image 643
user2173353 Avatar asked Feb 03 '26 14:02

user2173353


1 Answers

Your arguments are wrong in your controller function. The controller function accepts:

controller : function ($scope, $element) {
   ...    
}

If you are trying to inject ngModel as a dependency, use the link function instead:

link : function(scope, element, attrs, ngModelController) {
   ...
}
like image 86
sma Avatar answered Feb 05 '26 03:02

sma