RenleyRenfield
RenleyRenfield

Reputation: 321

$uibModalInstance undefined (AngularJS UI.Bootstrap)

Why is $uibModalInstance unable to be injected here?

http://plnkr.co/edit/mi9Ytv0HaqE47ENod4Gn?p=preview

baseController.$inject = ['$uibModal', '$uibModalInstance'];

function baseController($uibModal, $uibModalInstance) {

self.ok = function () {
$uibModalInstance.close(self.selected.item);
};

self.cancel = function () {
$uibModalInstance.dismiss('cancel');
};

I am trying to access $uibModalInstance and if I try to inject it, I get an injection error.

If I don't inject it, then it's Undefined...

Upvotes: 5

Views: 21265

Answers (3)

RenleyRenfield
RenleyRenfield

Reputation: 321

So LOTS of great statements here, but none of them quite solved the issue.

amg-argh got my plkr working with the way I had set up my injection

http://plnkr.co/edit/GXXmUosUEnEO3Tk0gUyp?p=preview

The biggest magic came from this edit here...

var childController = function ($scope, $uibModalInstance) {
        $scope.ok = function () {
            $uibModalInstance.close({ my: 'data' });
        }
        $scope.cancel = function () {                
            $uibModalInstance.dismiss();
        }
    }

    self.open = function (size) {

        var modalInstance = $uibModal.open({
            animation: self.animationsEnabled,
            templateUrl: 'help.html',
            controller: childController,
            size: size
        });
    };

+++++++++++++++++++++++++++++

I also want to make a note that this SHOULD be done later on as a Service, just as icfantv has pointed out. But I need to figure out the syntax for returning and consuming the modal's promise...

Thank you everyone for your help!!

Cheers!

Upvotes: 3

Rob J
Rob J

Reputation: 6629

There were a few things wrong with your plunk example:

The order in which you load your scripts is important, you had:

<script data-require="[email protected]" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js" data-semver="1.4.7"></script>
<script src="app.module.js"></script>
<script src="childController.js"></script>
<script src="baseController.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular-animate.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.14.3.js"></script>

This will not work as app.module.js depends on the angular-ui-bootstrap.js and childController.js depends on angular-animate.js and childController.js depends on baseController.js You need to load the scripts in the following order:

<script data-require="[email protected]" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js" data-semver="1.4.7"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular-animate.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.14.3.js"></script>
<script src="app.module.js"></script>
<script src="baseController.js"></script>
<script src="childController.js"></script>

In childcontroller.js, you have:

angular
      .module('app', ['ngAnimate'])

Which is recreating and overwriting the 'app' created in the app.module.js. You should inject the ngAnimate module in your app.module.js like so:

angular
    .module('app', ['ngAnimate', 'ui.bootstrap']); 

You don't need a reference to $uibModalInstance in your base controller, the:

var modalInstance = $uibModal.open({
  animation: self.animationsEnabled,
  templateUrl: 'help.html',
  controller: 'BaseController',
  size: size
});

gives you access to the modal you opened through 'var modalInstance' which has close and dismiss methods.

Upvotes: 1

icfantv
icfantv

Reputation: 4643

I suspect the reason your code is failing is because you're trying to inject the modal instance into the controller whose responsibility it is to create the modal. It can't inject it because it doesn't exist yet. Try using separate controllers: one for opening the modal and another for processing the modal contents. You can see an example of this in the Javascript portion of our modal example.

TBH, I've never seen dependencies injected that way before. Is there some problem you're solving by doing that? Any reason you're not just using:

angular.module(...).controller('MyController', ['dep1', dep2', ..., MyControllerFunction]);
function MyControllerFunction(dep1, dep2) {...}

Upvotes: 1

Related Questions