Unknown provider: $modalInstanceProvider <- $modalInstance in Angularjs modal - angularjs

I am using angular bootstrap ui modal which is working fine but when I try to close it using modalInstance it gives above error.Here is my code
var app = angular.module('LoginModule', ['ui.bootstrap']);
app.controller('LoginModal', ['$scope', '$modal', function ($scope, $modal) {
$scope.animationsEnabled = true;
$scope.open = function (size) {
var modalInstance = $modal.open({
animation: $scope.animationsEnabled,
templateUrl: '/app/template/Login.html',
controller: 'LoginController',
size: size
});
}
}]);
app.controller('LoginController', ['$scope', '$modalInstance', '$http', function ($scope, $modalInstance, $http) {
$scope.model = {};
$scope.loading = {
state: false
}
$scope.errors = '';
$scope.email = "";
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
}]);
I have created the cancel function in the controller which I specify with the template still it gives error.I use ng-click="cancel()" in button inside LoginController .
Need help?

Looks like you are instantiating the controller with ng-controller directive in the modal view. Instead you only need to use controller option of the modal in order to get the special dependency $modalInstance injected. If you have instantiated controller using ng-controller="LoginController" you need to remove it and you would not need it as well as the controller would automatically be instantiated (by resolving special dependency $modalInstance) and attached to the template.

Related

Angular bootstrap modal controller scope

I'm trying to get modals woking with angular bootstrap. I can launch the modal just fine, but I'm having some scope issues dismissing the modal.
When I launch the modal, I can specify a controller that I can call functions from, which works, but it seems to be a copy of the controller without a $parent and without any controller-local variables.
I need access to the return value of $uibModal.open() in order to close the modal, so I'm trying to store it in var modalInstance, which works fine when I'm within the scope of the controller, but the copy of the controller passed into the $uibModal service doesn't have the local variable modalInstance set.
I can get around this by storing the return object in the $rootScope, but that seems like a bad idea. Am I wrong? What's the best way to get access to modalInstance from the click handler passed into the $uibModal service? Can I avoid using the $rootScope?
var app = angular.module('main', ['ui.bootstrap']);
app.controller('MainCtrl', function($scope, $rootScope, $uibModal) {
var modalInstance;
$scope.launch = function() {
console.log('launch');
modalInstance = $uibModal.open({
template: '<div>Modal Content - <a ng-click="close()">Close</a></div>',
controller: 'MainCtrl',
});
// Wouldn't need to do this if I could access modalInstance in close handler
$rootScope.modalInstance = modalInstance;
}
$scope.close = function () {
console.log('close');
console.log(modalInstance);
// Works, but should I be using $rootScope like this?
//$rootScope.modalInstance.close();
// Doesn't work, modalInstance is undefined
modalInstance.close();
}
});
Angular instantiates a new instance of a controller whenever it is used, and it is the same for modal. So when you specify controller: 'MainCtrl' you're telling angular you want to instantiate one of those for your modal, which is rarely what you want.
Instead you should create a separate controller for the dialog, which can return values on closing using the $uibModalInstance service.
var app = angular.module('main', ['ui.bootstrap']);
app.controller('MainCtrl', function($scope, $rootScope, $uibModal) {
var modalInstance;
$scope.launch = function() {
console.log('launch');
modalInstance = $uibModal.open({
template: '<div>Modal Content - <a ng-click="close()">Close</a></div>',
controller: 'DialogCtrl',
});
....
}
});
app.controller('DialogCtrl', function($scope, $uibModalInstance) {
$scope.theThingIWantToSave = [];
$scope.cancel = function () {
$uibModalInstance.close($scope.theThingIWantToSave);
};
});

How to call ui bootstrap modal popup controller from within angular js another controller

how can i call angular ui bootstrap modal popup from inside another controller , as the condition is like instead of calling from view i need to call it from inside a function
App.controller('MailFolderController', ['$scope', '$http', '$timeout', '$stateParams', '$window', 'mails', '$interval', function ($scope, $http, $timeout, $stateParams, $window, mails, $interval) {
$scope.check = function(){
console.log("call parent ==========>")
// call open method in modal popup here
}
App.controller('orderCancellationController', ['$scope', '$modal', function ($scope, $modal) {
$scope.open = function (mail) {
var modalInstance = $modal.open({
templateUrl: '/orderCancellationBox.html',
controller: ModalInstanceCtrl,
resolve: {
mail: function () {
return mail;
}
}
});
};
// Please note that $modalInstance represents a modal window (instance) dependency.
// It is not the same as the $modal service used above.
var ModalInstanceCtrl = function ($scope, $modalInstance, mail) {
$scope.mail = mail;
$scope.submit = function () {
$scope.$parent.check();
$modalInstance.close('closed');
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
ModalInstanceCtrl.$inject = ["$scope", "$modalInstance", 'mail'];
}]);
}]);
so i want to call the open method in orderCancellationController from inside the check method , help !!
Following the example from my comment: Angular Calling Modal Open function from one controller to another
In order to open the modal from another controller you have to create a service, I did so in my app.js file, like so:
myApp.service('modalProvider',['$modal', function ($modal) {
this.openPopupModal = function () {
var modalInstance = $modal.open({
templateUrl: '/orderCancellationBox.html',
controller: 'ModalInstanceCtrl'
});
};
}]);
Then in the controller I wish to open my modal from, I inject the 'modalProvider' service, like so:
App.controller('MailFolderController', ['$scope', '$http', '$timeout', '$stateParams', '$window', 'mails', '$interval','modalProvider', function ($scope, $http, $timeout, $stateParams, $window, mails, $interval, modalProvider) {
// function to open modal
$scope.check = function(){
modalProvider.openPopupModal();
}

Modal Instance not resolving input

I am trying to use AngularUI modal's and I cannot seem to figure out why it is not resolving my variables.
Function that opens the modal and the modal instance
$scope.openModal = function (size, cert) {
var modalInstance = $modal.open({
template: 'ModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
certs: function () {
return $scope.certification;
}
}
});
modalInstance.result.then(function () {});
};
Modal Controller some stuff in here is leftover from debugging
angular.module('myApp').controller('ModalInstanceCtrl', ['$scope', '$filter', '$modalInstance', function ($scope, $filter, $modalInstance, certs) {
console.log(certs);
var results = $filter('filter')(certs, {id: id})[0];
$scope.cert = results;
$scope.ok = function () {
$modalInstance.close();
};
}]);
The main issue is that when it gets into the controller I am getting undefined for certs even though it should be resolved by the openModal function. I was following the official angular UI tutorial on how to do them here: Angular UI Bootstrap Modals
In your injection of 'certs' into your controller, you need to add it to the name declaration as well as the function.
angular.module('myApp').controller('ModalInstanceCtrl', ['$scope', '$filter', '$modalInstance', 'certs', function ($scope, $filter, $modalInstance, certs) {

How to pass data between controller on different files in Angularjs

I have a page with the Controller_1
the Controller_1 open a modal with a different controller on a different file that we call Controller_2
and then the Controller_2 open another modal that have a different controller on a different file that we call Controller_3
so we have:
Controller_1 --Open Modal--> Controller_2 --Open Modal--> Controller_3
when i close the modal with the Controller_3, I want to pass a value to the Controller_1.
my code:
Controller_1 open a modal with the Controller_2
app.controller("Controller_1", ['$scope', '$http', '$modal',
function ($scope, $http, $modal) {
$scope.openModal_1 = function () {
var modalInstance = $modal.open({
templateUrl: '/SomeFolder/FileWithController_2',
controller: 'Controller_2',
});
}
}]);
Controller_2 open a modal with the Controller_3
app.controller("Controller_2", ['$scope', '$http', '$modalInstance', '$modal',
function ($scope, $http, $modalInstance, $modal) {
$scope.SaveSomething = function () {
$http.post(url, obj)
.success(function (data) {
var modalInstance = $modal.open({
templateUrl: '/SomeFolder/FileWithController_3',
controller: 'Controller_3',
}
});
}).error(function () {
});
};
}]);
Controller_3 save something then close and pass some data to the Controller_1
app.controller("Controller_3", ['$scope', '$http', '$modalInstance',
function ($scope, $http, $modalInstance) {
$scope.SaveSomething = function () {
$http.post(url, obj)
.success(function (data) {
... pass some code to Controller_1 and close this modal.
});
}).error(function () {
});
};
}]);
Assuming that everything is working fine and all I want to do is passing some data from Controller_3 to Controller_1.
My question is:
How I can pass the data from Controller_3 to Controller_1?
I already tried pass the $scope when I open the modal as follows:
//from Controller_1 to Controller_2
var modalInstance = $modal.open({
templateUrl: '/SomeFolder/FileWithController_2',
controller: 'Controller_2',
scope: $scope,
});
in this case it work only for the Controller_2, so any modification on $scope will affect the Controller_1 but it is not working the same way if i do the same for Controller_3
I tried $emit and $on but it do not work too because they are not parent and child like this:
<div ng-controller="ParentCtrl">
<div ng-controller="ChildCtrl"></div>
</div>
they are complete different controllers in different files.
See $parent in Angular doc
Declare your modal instance,
var modalInstance = $modal.open({
templateUrl: '/SomeFolder/FileWithController_3',
controller: 'Controller_3',
scope: $scope.$parent,
});
So you can basically call a method or edit a property from controller_1 in your controller_3.
app.controller("Controller_3", ['$scope', '$http', '$modalInstance',
function ($scope, $http, $modalInstance) {
app.controller("Controller_3", ['$scope', '$http', '$modalInstance',
function ($scope, $http, $modalInstance) {
$scope.SaveSomething = function () {
$http.post(url, obj)
.success(function (data) {
$scope.$parent.modethodToCall(data);
})
.error(function () {});
};
}]);
I think you have to add another $parent because $modal create it's own child $scope. If someone can confirm ?
I personnaly won't recommand to use parent properties/methods. In my projects i create modal instance with params and return an object on modal closure. (See $modal in Angular ui doc)
$modalInstance.close(data);
You may use events and listen to these events.
Follow bellow an example:
app.controller('controller1', ['$scope','$rootScope', controller1]);
function controller1($scope, $rootScope){
$scope.$on('informController1', informController1);
function informController1(information){
//information displayed on the controller 1 related view
$scope.ctrl1Information = information;
}
}
app.controller('controller2', ['$scope','$rootScope', controller2]);
function controller2($scope, $rootScope){
//controller2 logic
}
app.controller('controller3', ['$scope','$rootScope', controller3]);
function controller3($scope, $rootScope){
$scope.$on('informController3', informController3);
function informController3(information){
//information displayed on the controller 3 related view
$scope.ctrl3Information = information;
}
function closeModal(){
//close modal code...
$rootScope.$broadcast('informController1', $scope.ctrl3Information);
}
}
For this approach to work, you have to make sure the controller is loaded when the event was triggered.

AngularJS $modalInstance - Can i do this in one controller?

I've spent some time having a play with the AngularJS Bootstrap popup, and for intents it's working great, but what i'd like to do is bind it, and it's dependant script to the same controller, what i can't get working is the close button now though. If i create a NEW controller, and inject $modalInstance it works great and i can wireup the close button without any issues at all, but i don't want a second controller, it seems to be over complication: i want all my controller logic in the formController really.
Why would i actually want two controllers? Passing the scope between two controllers just seems overkill to me, and the larger a project becomes the more un-managable it will become. Am i trying to over-simplify this unnecessarily? :)
The script:
(function(){
var app = angular.module('ngModalDemo', ['ui.bootstrap'])
.controller('formController', function($scope, $modal){
$scope.openModal = function () {
var modalInstance = $modal.open({
templateUrl: 'SomeModal.html',
controller: 'formController'
});
};
$scope.closeModal = function () {
// Code needed here :)
};
})
})();
The HTML body (excuse the HTML in script for the purposes of the DEMO):
<div ng-controller="formController">
<button class="btn btn-default" ng-click="openModal()">Let's do some stuff!</button>
<script type="text/ng-template" id="SomeModal.html">
<div class="modal-header">Do some stuff in this modal y'all.</div>
<div class="modal-footer">
<button class="btn btn-info" ng-click="closeModal()">Close</button>
</div>
</script>
</div>
The answer based on Kaspars' input :)
(function(){
var app = angular.module('ngModalDemo', ['ui.bootstrap'])
.controller('formController', function($scope, $modal, $log){
$scope.openModal = function () {
var modalInstance = $modal.open({
templateUrl: 'SomeModal.html',
controller: [
'$scope', '$modalInstance', function($scope, $modalInstance){
$scope.closeModal = function () {
$modalInstance.close();
};
}
]
});
};
})
})();
I was struggling with the same problem and the best thing I came up with was to use anonymous function as a modal controller. In that way all the logic is in the same controller and you don't have to create separate controller for each modal window.
This would look like this:
(function(){
var app = angular.module('ngModalDemo', ['ui.bootstrap'])
.controller('formController', function($scope, $modal){
$scope.openModal = function () {
var modalInstance = $modal.open({
templateUrl: 'SomeModal.html',
controller: [
'$scope', '$modalInstance', 'data', function($scope, $modalInstance, data) {
$scope.data = data;
$scope.ok = function() {
$modalInstance.close();
};
$scope.closeModal = function() {
$modalInstance.dismiss();
};
}
]
});
};
})
})();
PS. Haven't tested code above, just put it together from your provided code and fragments from one of my projects.
You can also try this
var modalInstance = $modal.open({
templateUrl : 'someTemplate.html',
scope : $scope,
size : 'md'
});

Resources