I've been playing around with this bug but I can't seem to figure it out. The problem started when I pushed the angular-bootstrap models I had added to the prod server. The original error was this:
"AngularJS Error: Unknown provider: aProvider <- a"
I'm pretty sure I was getting that error because my files weren't minifying correctly. So I went through my controllers and found that I wasn't $injecting $modal instance into my controllers and that's when I ran into this problem.
Whenever I inject $modalInstance into my controller in the minified format I get this error. I am not using the format angular-bootstrap suggests because I have a lot going on and many controllers on the site I'm building so I combined everything into one controller instead of several functions.
My Controller:
.controller('CreateGroupCtrl', ['$scope', '$http', '$window', '$cookies', '$modal', '$log', 'FeedService', '$modalInstance',
function CreateGroupCtrl($scope, $http, $window, $cookies, $modal, $log, $modalInstance, FeedService) {
$scope.createGroupCall = function createGroupCall(teacher, name) {
if(teacher != null && name != null) {
FeedService.createGroupCall($cookies.token, $window.sessionStorage.user, teacher, name).success(function(data) {
console.log('GroupCreated');
}).error (function(status,data,token) {
console.log(status);
console.log(data);
});
} else {
alert("Error!");
}
}
/***********ANGULAR-UI MODAL CODE**********/
$scope.open = function (size) {
var modalInstance = $modal.open({
templateUrl: 'CreateGroupContent.html',
controller: CreateGroupCtrl,
size: size
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
$scope.ok = function () {
$modalInstance.close();
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
}]);
My Template:
<button ng-controller="CreateGroupCtrl" ng-click="open()" type="button" id="creategroup" class="btn ns-btn">
<img class="ns-add" src="images/createGroup.png">
<p class="create">Create Group</p>
</button>
<div>
<script type="text/ng-template" id="CreateGroupContent.html">
<div class="modal-header">
<h2 class="modal-title ns-modal-title">Create A Group</h2>
<button class="ns-modal-close" ng-click="cancel()"><img src="images/xCancel.png"></button>
</div>
<div class="modal-body">
<form class="form-signin" role="form">
<input type="text" class="form-control ns-modal-form" placeholder="Teacher" ng-model="create.teacher" required autofocus>
<input type="text" class="form-control ns-modal-form" placeholder="Group Name" ng-model="create.name" required>
</form>
</div>
<div class="modal-footer">
<button class="btn ns-modal-add ns-btn" ng-click="createGroupCall(create.teacher, create.name); ok();" type="submit">Create</button>
</div>
</div>
</script>
</div>
At first, you need to inject all in its order.
Also, you should inject $modal into the controller in which you would like to create your modal view. And the $modalInstance can be injected ONLY into the controller which is used for this $modal window. In your case you use the same controller, so you couldn't inject $modalInstance
Demo: http://plnkr.co/edit/khzNQ0?p=preview
Also, in your case (when you use only 1 controller) - you can pass as object field scope which will be used as parent of $scope for your modal view. By default it is $rootScope, but you can type:
$scope.open = function (size) {
var modalInstance = $modal.open({
templateUrl: 'CreateGroupContent.html',
controller: CreateGroupCtrl,
size: size,
scope: $scope
});
So now your functions ok() and cancel() will be available in your modal view and modal scope.
Looks like your FeedService and $modalInstance are mixed up. They need to be in the same order.
Related
I've a strange behavior using multiple transclude component in Angularjs:
changes in first slot model no visible in controller.
<div ng-app="myApp" ng-controller="testController">
<script type="text/ng-template" id="component-template.html">
<div style="color:red;" ng-transclude="heading">
</div>
<div style="color:blue;" ng-transclude="body">
</div>
</script>
Example1
<input ng-model="example1Model"/>
<test-component>
<panel-heading>
Example2
<input ng-model="example2Model"/>
</panel-heading>
<panel-body>
Example1Result:{{example1Model}}<br/>
Example2Result:{{example2Model}}
</panel-body>
</test-component>
</div>
<script>
angular.module("myApp", [])
.controller("testController", function ($scope, $location) {
})
.component("testComponent", {
templateUrl: "component-template.html",
transclude: {
heading: "panelHeading",
body: "panelBody"
},
controller: function ($scope, $element, $attrs) {
this.$doCheck = function () {
//do anything
}
}
});
</script>
Now if you try to test it in this JSfiddle:https://jsfiddle.net/Lpveophe/1/
Why binding model example2Model did not working?
However example1Model binding model working correctly.
You need to use . in ng-model to make it work. For better understand of scope, please go through this article: https://github.com/angular/angular.js/wiki/Understanding-Scopes
To make it work, replace example2Model with o.example2Model everywhere and change your controller to:
.controller("testController", function ($scope, $location) {
$scope.o = {};
$scope.o.example2Model = '';
})
I have an app with modals which I'm trying to call using $modalInstance. According to the other questions I've read here, I shouldn't include ng-controller in my template and that's exactly what I did, however it's still not working.
Here's my code:
HTML - main page
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.0.js"></script>
HTML - add.html template
<div ng-show="showAddModal">
<div class="product-header">
<div class="modal-title">Add Product Information</div>
<div class="modal-close" ng-click="closeModal();">X</div>
</div>
<!-- other codes go here -->
</div>
AngularJS - app.js
var app = angular.module('ProductApp', ['ngResource', 'ui.bootstrap']);
AngularJS - controller
app.controller('MainController', ['$scope', '$resource', '$http', 'ProductFactory', 'EditProductFactory', '$modalInstance',
function ($scope, $resource, $http, ProductFactory, EditProductFactory, $modalInstance) {
$scope.addProduct = function () {
$scope.showAddModal = true;
var modalOptions = {
template: '/views/add.html',
controller: 'AddController'
//scope: $scope
};
$modal.open(modalOptions);
}
...
Any tips would be greatly appreciated.
Thank you.
You need to inject $uibModal instead of $modalInstance in your calling controller. And use $uibModal.open(...).
In your AddController you can inject $uibModalInstance
angular.module('ProductApp').controller('AddController', function ($scope, $uibModalInstance) {
$scope.close = function () {
$uibModalInstance.close();
};
});
I'm trying to get an Angular Bootstrap UI Modal (0.14) working. I can get the modal to pop up (great) but the data object I'm passing is null (it isn't null when i set it). I've looked at all sorts of plukners, which I see how they work, mine just doesn;t seem to work.
Below, I've rigged it to pass some made up data, in
(function () {
'use strict';
angular.module('MPAapp')
.controller('workCentreCtrl',
['$scope', '$rootScope', 'toastrFactory', 'workCentreResource', '$uibModal', '$log',
workCentreCtrl])
function workCentreCtrl($scope, $rootScope, toastrFactory, workCentreResource, $uibModal, $log) {
var scope = this;
var slot = [{'slot1':5}, {'slotname':'dynamo'},{'OriginalSlot':5}]
var max = 5
// Click event from the view
$scope.EditWorkOrder = function () {
var modalInstance = $uibModal.open({
animation: true,
templateUrl: '/app/WorkOrder/Views/EditWorkOrder.html',
controller: 'EditWorkOrderCtrl',
size: 'lg',
resolve: {
data: function () {
return{
Slot: slot,
Max: max
}
}
}
});
modalInstance.result.then(function () {
$log.info('do some UI update here');
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
}
}());
/* END PARENT CONTROLLER */
/* --------------------------------*/
/* MODAL INSANCE CONTROLLER BEGIN*/
(function () {
'use strict';
angular.module('MPAapp')
.controller('EditWorkOrderCtrl', ['$scope', '$timeout', 'toastrFactory',
EditWorkOrderCtrl]);
EditWorkOrderCtrl.$inject = ['$uibModalInstance', 'data']
function EditWorkOrderCtrl($scope, $timeout, toastrFactory, $uibModalInstance, data) {
var scope = this;
$scope.ok = function () {
$uibModalInstance.close(scope.Slot);
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
// THIS IS WHEN DATA IS UNDEFINED.
scope.Slot = data.Slot;
scope.SlotNumber = data.Slot.OriginalSlot;
}
}());
And the HTML in the modal instance
<div ng-controller="EditWorkOrderCtrl as vm">
<div class="row">
<div class="col-md-12">
<h2>Edit Work Order {{vm.Slot.WorkOrderNumber}}</h2>
</div>
</div>
<div class="row">
<div class="col-md-12"><span class="main-text bold">Product:</span> {{vm.Slot.ProductCode}} - {{vm.Slot.ProductDescription}}</div>
</div>
<div class="row">
<div class="col-md-6">
<span class="main-text bold">Size:</span> {{vm.Slot.QuantityRequired}}
<span class="main-text bold">Time (mins):</span> {{vm.Slot.StandardRunTime}}
<span class="main-text bold">Current Date:</span>{{vm.Slot.OriginalOrderDate | date:'dd MMM yyyy'}}
</div>
<div class="col-md-6"></div>
</div>
</div>
Any help very much appreciated. I'm still quite new to Angular, it's proving a tough nut in some areas, but I love it!
Of course data is not going to be available like this (but it's not null, it's undefined). Your dependency injection is messed up. Note, that what you are describing in $inject array, must correspond to formal parameters passed to controller function.
In your case with this configuration:
EditWorkOrderCtrl.$inject = ['$uibModalInstance', 'data']
function EditWorkOrderCtrl($scope, $timeout, toastrFactory, $uibModalInstance, data) {}
you tell Angular to inject $uibModalInstance as $scope, and data as $timeout. Clearly not what you want.
Correct injection should look like
EditWorkOrderCtrl.$inject = ['$scope', '$timeout', 'toastrFactory', '$uibModalInstance', 'data'];
function EditWorkOrderCtrl($scope, $timeout, toastrFactory, $uibModalInstance, data) {}
Alternatively you can use array notation as controller definition:
.controller('EditWorkOrderCtrl', ['$scope', '$timeout', 'toastrFactory', 'workCentreResource', 'blockedDatesResource', 'data', EditWorkOrderCtrl]);
but in this case make sure you don't use EditWorkOrderCtrl.$inject = ['$uibModalInstance']. Remove it because it has higher priority and as I explained above it's messed up.
Also take a look at this answer, where I provided detail explanation about different injection methods.
I have school task.
We have a HTML code like this:
<html ng-app="myTest">
<head><script type="text/javascript" src="../myScript.js"></script>
</head>
<body id="tst" class="textpage" ng-controller="TestController as testcon">
<form class="" id="frm" ng-submit="doStuff()">
<div class="form-group">
{{testinfo}}
</div>
<div class="form-group">
<button type="submit" id="sbtn" name="sbtn">testSubmit</button>
</div>
</form>
</body>
</html>
Content of javascript with name myScript.js is this:
var tester = angular.module('myTest', ['ui.mask']);
tester.controller('TestController', ['$scope', '$http', '$location', '$window', function ($scope, $http, $location, $window) {
$scope.doStuff = function () {
{
$scope.testinfo = 'unknown value';
};
};
}
]);
I have option to add new javascript.
But I am not possible to get value from $scope.testninfo.
I cannot edit existing JavaScript and cannot edit HTML file. I can just add new javascript.
Is there option how to get value from $scope.testinfo in another javascript?
Thanks.
You can use broadcast
From controller 1 we broadcast an event
$scope.$broadcast('myEvent',anyData);
controller 2 will receive our event
$scope.$on('myEvent', function(event,anyData) {
//code for controller 2
});
here anyData represent your object to be passed
Use ng-model.
<div class="form-group">
<input type="text" ng-model="testinfo">
</div>
I dont think it is possible without appending the existing javascript/html. Because the $scope of the TestController cannot be accessed from another controller (file).
If you COULD append the HTML you could use the $rootscope, in that way the value, which is set by the TestController is accessible from another controller. Or you can add a Global app value. I created a fiddle which show the two options: https://jsfiddle.net/Appiez/wnyb9pxc/2/
var tester = angular.module('myTest', []);
tester.value('globalVar', { value: '' });
tester.controller('TestController', ['$rootScope', '$scope', '$http', '$location', '$window', 'globalVar', function ($rootScope, $scope, $http, $location, $window, globalVar) {
$scope.doStuff = function () {
{
$rootScope.testinfo = 'this is the new value';
globalVar.value = 'a global value';
};
};
}
]);
tester.controller('TestController2', ['$rootScope', '$scope', 'globalVar', function ($rootScope, $scope, globalVar) {
$scope.doStuff2 = function () {
{
alert($rootScope.testinfo);
alert(globalVar.value);
};
};
}
]);
This is what services are for in angular. They ferry data across controllers. You can use NG's $broadcast to publish events that contain data, but Providers, Services, and Factories are built to solve this.
angular.module('krs', [])
.controller('OneCtrl', function($scope, data){
$scope.theData = data.getData();
})
.controller('TwoCtrl', function($scope, data){
$scope.theData = data.getData();
})
.service('data', function(){
return {
getData: function(){
return ["Foo", "Bar"];
}
}
});
Here's a fiddle to help get you into the swing of things. Good luck in school!
I am able to open a model dialog using the following javascript code but with minified version, I am not able to open model dialog. I am getting back an error saying:
Error: [$injector:unpr] Unknown provider: aProvider <- a
http://errors.angularjs.org/1.2.11/$injector/unpr?p0=aProvider%20%3C-%20a
at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.js:78:12
at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.js:3543:19
at Object.getService [as get] (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.js:3670:39)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.js:3548:45
at getService (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.js:3670:39)
at invoke (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.js:3697:13)
at Object.instantiate (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.js:3718:23)
at $get (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.js:6777:28)
at resolveSuccess (http://localhost:8080/SampleTest/ui-bootstrap-tpls-0.10.0.js:1710:32)
at deferred.promise.then.wrappedCallback (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.js:10949:81) angular.js:9419
Here is the code with which I am able to open model dialog:
HTML:
<!DOCTYPE html>
<html ng-app="dialogexample">
<head>
<title>Dialog Test</title>
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/>
</head>
<body>
<div ng-view=""></div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular-route.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular-resource.min.js"></script>
<script src="ui-bootstrap-tpls-0.10.0.js"></script>
<script type="text/javascript" src="appscript.js"></script>
</body>
</html>
appscript.js:
var dialogexample = angular.module('dialogexample', ['ngRoute', 'ui.bootstrap']);
dialogexample.config(function($routeProvider) {
$routeProvider
.when('/dialogpage', {
templateUrl: "dialogpage.html",
controller: 'dialogController'
})
.otherwise({ redirectTo: '/dialogpage' });
});
dialogexample.controller('dialogController', function ($scope, $location, $modal, $rootScope) {
$scope.openDialog = function() {
showDialog();
};
function showDialog() {
$modal.open({
template: '<div>'+
'<div class="modal-header">' +
'<h3>Dialog</h3>'+
'</div>'+
'<div class="modal-body">'+
'<p>'+
'Dialog Opened'+
'</p>'+
'</div>'+
'<div class=\"modal-footer\">'+
'<button class="btn btn-primary" ng-click="ok()">OK</button>'+
'<button class="btn btn-warning" ng-click="cancel()" ng-hide="hidecancel">Cancel</button>'+
'</div>'+
'</div>',
controller: function ($scope, $modalInstance) {
$scope.ok = function () {
$modalInstance.close();
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
}
});
};
});
dialogpage.html
<div class="partialviewpage">
<button ng-click="openDialog()">Show Dialog</button>
</div>
Then I minified appscript.js using the steps given in the URL below:
http://chrislarson.me/blog/how-minify-angularjs-scripts
Here is my minified appscript.min.js:
var dialogexample=angular.module("dialogexample",["ngRoute","ui.bootstrap"]);dialogexample.config(["$routeProvider",function(a){a.when("/dialogpage",{templateUrl:"dialogpage.html",controller:"dialogController"}).otherwise({redirectTo:"/dialogpage"})}]);
dialogexample.controller("dialogController",["$scope","$location","$modal","$rootScope",function(a,e,c,f){function d(){c.open({template:'<div><div class="modal-header"><h3>Dialog</h3></div><div class="modal-body"><p>Dialog Opened</p></div><div class="modal-footer"><button class="btn btn-primary" ng-click="ok()">OK</button><button class="btn btn-warning" ng-click="cancel()" ng-hide="hidecancel">Cancel</button></div></div>',controller:function(a,b){a.ok=function(){b.close()};a.cancel=function(){b.dismiss("cancel")}}})}
a.openDialog=function(){d()}}]);
After adding this script to HTML file, I was not able to open model dialog. Please let me know how can I show the model dialog using minified javascript.
Any help is appreciated.
you also have to correctly inject parameters passed into $modal controller
let's say
ctrl.$inject = ['$scope', '$modalInstance'];
ctrl = function ($scope, $modalInstance) {
$scope.ok = function () {
$modalInstance.close();
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
$modal.open({
template: ...,
controller: ctrl
});
edit: syntax mistakes
Variable names get shortened when minifing so the dependency injector cannot work correctly.
Read the note on minification:
http://docs.angularjs.org/tutorial/step_05
The error is caused because of the way your services are injected
Take a look at this link: https://docs.angularjs.org/tutorial/step_05
For instance this your controller:
dialogexample.controller('dialogController', function ($scope, $location, $modal, $rootScope) {...}
Should look this way:
dialogexample.controller('dialogController', ['$scope', '$location', '$modal','$rootScope', function ($scope, $location, $modal, $rootScope) { ... }]);
The controller inside your $modal:
controller: function ($scope, $modalInstance) { ...},
Should look this way:
controller: ('modalController', ['$scope', '$modlaInstance',
function ($scope, $modalInstance) { ... }]) //add comma after <)> if other options comes after
Do the same to your config too
Should look this way:
dialogexample.config(['$routeProvider', function($routeProvider) { .. }]);