20

This is a bit strange. When I search this issue online I see many pages of Google results and SO solutions... but none seem to work!

In a nutshell, I am trying to implement AngularUI Bootstrap Modal. I keep getting the following error:

Error: [$injector:unpr] Unknown provider: $uibModalInstanceProvider <- $uibModalInstance <- addEntryCtrl

Here is my HTML:

<nav class="navbar navbar-default">
  <div class="container">
    <span class="nav-col" ng-controller="navCtrl" style="text-align:right">
      <a class="btn pill" ng-click="open()" aria-hidden="true">Add New</a>
    </span>
  </div>
</nav>

Here is my controller:

var app = angular.module('nav', ['ui.bootstrap']);

app.controller('navCtrl', ['$scope', '$uibModal', function($scope, $uibModal) {
  $scope.open = function() {
    var uibModalInstance = $uibModal.open({
      animation: true,
      templateUrl: 'addEntry/addEntry.html',
      controller: 'addEntryCtrl',
    });
  };
}]);

And finally, here is my modal code:

var app = angular.module('addEntry', ['firebase', 'ui.bootstrap']);

app.controller('addEntryCtrl', ['$scope', '$firebaseObject', '$state', '$uibModalInstance', function($scope, $firebaseObject, $state, $uibModalInstance) {
  $scope.cancel = function() {
    $uibModalInstance.dismiss('cancel');
  };

  $uibModalInstance.close();
}]);

Solutions I've tried:

  • updated both Angular Bootstrap (Version: 0.14.3) and Angular (v1.4.8)
  • changed uibModalInstance to modalInstance
  • changed $uibModalInstance to modalInstance
  • put my addEntryCtrl inside my ModalInstance

Any thoughts? This has been driving me up the wall for almost 2 days now.

* EDIT *

I should note two things:

1) when I remove $uibModalInstance as a dependency from addEntry, my HTML form submit buttons work just fine and the form looks perfect. Even the redirect occurs correctly (upon submission). The problem remains: the modal still stays on the screen and an error is thrown that $uibModalInstance is undefined. This makes sense since I removed it as a dependency but I obviously still need the modal is close upon submission.

2) Also, I have almost identical code working in another part of my app. The only difference there is that it's working via a factory. Otherwise, the code is identical. Thus, I am confident my dependencies are all there and versions are correct. So. Freaking. Strange.

Thanks!

Benjamin Hoffman
  • 797
  • 1
  • 6
  • 18
  • Are those code blocks within an IIFE? Otherwise, you're overwriting the `app` variable (could prove troublesome). Also, your second code block contains an unclosed function and array. It's probably a typo or you just omitted the latter parts but you should try to make the code in your questions complete – Phil Nov 26 '15 at 04:48
  • Also, I've seen this same error before (http://stackoverflow.com/q/33600137/283366) but that question didn't get any useful answers. FYI, `$uibModalInstance` works fine in my apps – Phil Nov 26 '15 at 04:51
  • Any chance you're using ui-bootstrap 0.14.2? `$uibModalInstance` was added in 0.14.3 ~ https://github.com/angular-ui/bootstrap/issues/4778 – Phil Nov 26 '15 at 04:55
  • @Phil thanks for the response! 1) i edited my code to include closing brackets, 2) i included the version of bootstrap and angular..... still no dice :( – Benjamin Hoffman Nov 26 '15 at 05:58

5 Answers5

49

Answer Found! After hacking away with my friend, we discovered the answer. I wanted to post it here just in case someone else reads this.

It turns out that we had an ng-controller in our modal window that was in a div tag that wrapped the entire html form that was in the modal. Previously, this worked fine when our form was NOT in a modal (it had a separate URL) but for some reason it breaks when it is in a modal. The ng-controller was referencing the addEntryCtrl. Immediately after removing it, the form worked!

Benjamin Hoffman
  • 797
  • 1
  • 6
  • 18
20

The problem was that you were specifying a (or double) controller(s) in 2 places- when opening a modal and inside a template - this is not needed. Remove ng-controller from a template and things will work as expected.Trust me,it will work.

napoleonjk
  • 229
  • 2
  • 6
  • This is the best answer. – Jeremey Jun 07 '16 at 20:45
  • This is exactly the problem I'm facing. Since I just want to use the directive, so I don't have my own controller. I put the controller of the directive into the tag, it caused the problem. Removing the ng-controller attribute resolved it perfectly. Thanks! – hailong Dec 20 '16 at 05:00
  • This answer it totally wrong - Check this Fiddle: https://jsfiddle.net/s8bLdg2d/ or this plnkr https://plnkr.co/edit/FElOoLllZmT7kaGVtz5V?p=preview – lin Nov 23 '17 at 17:16
  • This is the best answer. Keep it up. – PAWAN RAJ Shakya Feb 11 '18 at 23:22
8

It turns out that if you specify the controller inside the html template (with ng-controller="...") it will not resolve the $uibModalInstance. Specifying the controller from the call to $uibModal.open({controller="...", ...}) will allow it to resolve correctly.

Since you only need the dismiss() and close() methods, you can get them from $scope (named $dismiss and $close) instead, since that will resolve correctly in both ways of instantiating the controller.

var app = angular.module('addEntry', ['ui.bootstrap']);
app.controller('addEntryCtrl', ['$scope', function($scope) {
    $scope.cancel = function() {
        $scope.$dismiss('cancel');
    };

    $scope.$close();
}]);
Arjan Einbu
  • 13,543
  • 2
  • 56
  • 59
3

You are trying to reference a controller that is part of a separate module. In order for this to work, you need to inject your secondary module (addEntry) into your main module (nav):

var app = angular.module('nav', ['ui.bootstrap', 'addEntry']);
Andy W
  • 594
  • 2
  • 12
1

As you use $uibModal.open() (see lower) and specify explicitly the controller name, you shouldn't put the directive ng-controller in the template. That cause the error. No ng-controller in the View !

 var uibModalInstance = $uibModal.open({
  animation: true,
  templateUrl: 'addEntry/addEntry.html',
  controller: 'addEntryCtrl',
});
icedfluid
  • 11
  • 1