i need to pass an object to modal controller , i have tried different approach , here is my final code , the object is passed but i get big error in console
Error: [$injector:unpr]
here is my code
vm.openAttendeesModal = function (meeting) {
var modalInstance = $modal.open({
templateUrl: '/App/Main/views/meetings/AttendeesModal.cshtml',
controller: 'attendeeController',
resolve: {
meetingSelected: function () { return meeting }
}
});
}
and here is my modal controller
angular
.module('App')
.controller('attendeeController', attendeeController);
attendeeController.$inject = ['meetingSelected', '$scope', '$modal', 'meetingService'];
function attendeeController(meetingSelected,$scope, $modalInstance, meetingService) {
/* jshint validthis:true */
var vm = this;
vm.meetingSelected = meetingSelected;
and here is complete error
angular.js:12520 Error: [$injector:unpr] http://errors.angularjs.org/1.4.8/$injector/unpr?p0=meetingSelectedProvider%20%3C-%20meetingSelected%20%3C-%20attendeeController
at Error (native)
the funny part is everything is working , even i have access to passed object , but i just feel something is wrong because of that fat error.
any suggestion ?
thanks
try this
var modalInstance = $modal.open({
templateUrl: '/App/Main/views/meetings/AttendeesModal.cshtml',
controller: 'attendeeController as ctrl',
resolve: {
meetingSelected: function () { return meeting }
}
});
or add controllerAs: "ctrl"
Edit:
if you add "attendeeController as ctrl" in AttendeesModal.cshtml remove it.
Related
Calling one controller to another controller AngularJS
I have had code that opens a modal and call another controller.
List Controller
$scope.addPayable = function (booking) {
var modalInstance = $uibModal.open({
templateUrl: 'views/pages/dashboard/reports/payables.modal.html',
controller: 'payableCtrl',
resolve: {
data: function () {
return {
amount: "123"
};
}
}
});
};
This is my second controller
Payable Controller
'use strict';
angular.module('AniTheme')
.controller('payableCtrl', ['$scope', '$data', 'uibModalInstance', function ($scope, data, $uibModalInstance) {
}]);
console screen of my browser shows me an error.
The main purpose of doing this, I want to pass some data to the modal screen.
I have an Angular 1.2 project, and I have a controller which I want to replace using Component. This new component is open from uibModal and it contains another directive.
Before changing it to a component, everthing was fine, but after I changed it I get an error: Unknown provider: $uibModalInstanceProvider
First component:
$ctrl.openImportModal = function () {
var modalInstance = $uibModal.open({
templateUrl: 'forecastDataNew/modals/importStaffingPlanJobModal/importStaffingPlanJobModal.tpl.html',
component: 'importStaffingPlanJobModalCtrl',
windowTopClass: 'import-forecast-data-modal',
size: 'sm',
backdrop: 'static'
});
...
Second component (which throws the error when I change a component to a controller):
angular.module('nice.saas.wfm.importStaffingJob')
.component('importStaffingPlanJobModalCtrl', {
templateUrl: 'forecastDataNew/importStaffingPlanJobs.tpl.html',
bindings: { },
controller: function($q, $scope, $log, $uibModalInstance, Utils, ForecastDataService) {
'use strict';
$scope.filePicked = false;
$scope.file = { };
$scope.isClicked = true;
$scope.uploadCsvAndSave = function(file) {
This component includes its HTML directive — if I remove that directive, no error occurs.
angular.module('nice.saas.wfm.importStaffingJob',['firebase', 'ui.bootstrap'])
Try with this module definition.
I have a little issue by using a customize directive within the template field of UI-Bootstrap modal directive.
My aim is send data to modal via resolve attribute and re-use these resolved parameters inside the controller of my own directive.
var app = angular.module('app', ['ui.bootstrap']);
app.controller('MyCtrl', ['$scope', '$modal', function($scope, $modal) {
$scope.openModal = function () {
var popup = $modal.open({
template: '<my-modal></my-modal>',
resolve : {
mydata : function() {
return 42;
}
}
});
};
}]);
app.controller('ModalController', ['$scope', 'mydata', function($scope, mydata) {
//The error is in this directive controller
$scope.mydata = mydata;
}]);
app.directive('myModal', function() {
return {
restrict: 'E',
templateUrl : 'mymodal.html',
controller : 'ModalController',
replace: true
};
});
Maybe I proceed in the wrong way.
Any suggest to make this code functionnal ?
http://plnkr.co/edit/RND2Jju79aOFlfQGnGN8?p=preview
The resolve parameters are only injected to the controller defined in the $modal.open config parameters, but you want to inject it to the directive controller. That will not work. Imagine you would use the myModal directive somewhere else, there wouldn't be a myData object that could be used.
But i don't realy see, what you need the directive for. You could go much easier this way:
app.controller('MyCtrl', ['$scope', '$modal',
function($scope, $modal) {
$scope.openModal = function() {
var popup = $modal.open({
templateUrl: 'mymodal.html',
controller: 'ModalController',
resolve: {
mydata: function() {
return 42;
}
}
});
};
}
]);
// Here the mydata of your resolves will be injected!
app.controller('ModalController', ['$scope', 'mydata',
function($scope, mydata) {
$scope.mydata = mydata
}
]);
Plunker: http://plnkr.co/edit/bIhiwRjkUFb4oUy9Wn8w?p=preview
you need to provide an Object "mydata". Ensure, that you have a correct implemented factory which provides your myData Object. If you had done that, you can "inject" your myData Object where ever you want to.
yourApp.MyDataFactory = function () {
var myData = {i: "am", an: "object"};
return myData;
}
this would provide an "myData" Object
I'm not sure what you are trying to accomplish with the directive, but if you are trying to provide a generic way to invoke the $model, that you can then use from many places in your app, you may be better off to wrap $model with a service. Than you can then call from other places in your app.
I forked and modified your plunkr to work this way: http://plnkr.co/edit/0CShbYNNWNC9SiuLDVw3?p=preview
app.controller('MyCtrl', ['$scope', 'modalSvc', function($scope, modalSvc) {
var mydata = {
value1: 42
};
$scope.openModal = function () {
modalSvc.open(mydata);
};
}]);
app.factory('modalSvc', ['$modal', function ($modal) {
var open = function (mydata) {
var modalInstance,
modalConfig = {
controller: 'ModalController',
resolve: {
mydata: function () {
return mydata;
}
},
templateUrl: 'mymodal.html'
};
modalInstance = $modal.open(modalConfig);
return modalInstance;
};
return {
open: open
};
}]);
Also, I changed mydata to be an object, rather than '42', as I am sure you will have other data to pass in. the markup was updated accouringly:
<div class="modal-body">
BODY {{mydata.value1}}
</div>
Doing it this way, the resolve property works, and you can get your data.
As for the other answers mentioning you must define mydata, the resolve property passed into $model does this for you, so it can be injected into the modal's controller (ModalController), like you have done.
I have a very weird problem and as I can't really copy the actual production code here or at least not much of it, you probably can't help me, but I'll try nevertheless.
Here is a simplified example of what I'm doing:
http://plnkr.co/edit/7IjX4jV9sb2Fb6NpmzUZ?p=preview
angular.module("hello", [
"ui.bootstrap",
"ui.bootstrap.tpls",
]);
angular.module("hello").controller("helloCtrl", function($scope, $modal){
$scope.openModal = function(){
var modalInstance = $modal.open({
templateUrl: 'modal.tpl.html',
controller: 'modalCtrl',
resolve: {
obj1: function(){
return {name:"obj1"};
},
obj2: function(){
return {name:"obj2"};
}
}
});
};
});
angular.module("hello").controller("modalCtrl", function($scope, obj1, obj2){
$scope.obj1 = obj1;
$scope.obj2 = obj2;
})
So I'm opening a modal and resolving the object's to be used in the modal's controller. That example works, but in the real code the obj1 will be resolved to what was supposed to be obj2, and obj2 will be undefined. They are also already wrong when they come to controller, not just after attaching them to scope.
In the real project I'm also using ui-router, but the modal is not it's own state and nothing with those names is resolved in this state or parent states.
If someone has any ideas or wild guesses of what could be causing such behavior, I would really appreciate to hear them.
Edit:
Here are the most relevant parts of the production code:
modal opening controller:
angular.module('cmt').controller('createClusterModalCtrl', function ($scope, $modal, clusterSvc) {
$scope.openCreateClusterModal = function () {
var modalInstance = $modal.open({
templateUrl: '..path to template..',
controller: 'clusterCreateCtrl',
windowClass: 'cmt-xl-modal-window',
resolve: {
initTab: 0,
validationSettings: function(){
//return something simple for debug
return {name:"validation"};
},
cluster: function(){
//return something simple for debug
return {name: "cluster"};
}
}
});
};
});
modal controller:
angular.module('cmt').controller('clusterCreateCtrl', function ($scope, $modalInstance, clusterSvc, toastr, initTab, validationSettings, cluster) {
console.log("validation:");
console.log(validationSettings); //will print name: "cluster"
console.log("cluster:");
console.log(cluster); //will print undefined
......
Found the error:
that resolve "initTab: 0" caused it to get the next defined function and so fort. I had to change it to a function that returns 0.
Would someone care to explain why you can not resolve to something else than a function?
I am trying to do an asynchronous http request to load some data before my app loads and so I am using a resolve in $routeProvider which is an http request in my MainController. For some reason, I keep getting Error: [$injector:unpr] Unknown provider: appDataProvider <- appData where appData is where I do my http request. I am using AngularJS v 1.2.5.
Here is the code and two methods that I tried that both give the same error:
Method #1
MainController.js
var MainController = ['$scope','$location','appData',
function($scope, $location, appData){
console.log(appData.data);
}
];
MainController.loadData = {
appData: function($http, $location, MainFactory){
var aid = MainFactory.extractAid($location);
return $http({method: 'GET', url: URL_CONST + aid});
}
};
app.js
var app = angular.module('HAY', ['ngRoute']);
app.config(function($routeProvider) {
$routeProvider
.when('/', {
redirectTo: '/pages/alerts'
})
.when('/pages/:pageName', {
templateUrl: function(params) {
return 'views/pages/' + params.pageName + '.html';
},
controller: MainController,
resolve: MainController.loadData
})
.otherwise({
redirectTo: '/pages/alerts'
});
});
I tried changing the name in case it was a conflicting system reserved keyword but with no luck. For some reason, appData is never recognized
Method #2
I also tried changing it around like so:
app.js
var app = angular.module('HEY', ['ngRoute']);
app.config(function($routeProvider) {
$routeProvider
.when('/', {
redirectTo: '/pages/alerts'
})
.when('/pages/:pageName', {
templateUrl: function(params) {
return 'views/pages/' + params.pageName + '.html';
},
controller: MainController,
resolve: {
appData: ['$http', '$location','MainFactory', function($http, $location, MainFactory) {
var aid = MainFactory.extractAid($location);
return $http({method: 'GET', url: URL_CONST + aid});
}]
}
})
.otherwise({
redirectTo: '/pages/alerts'
});
});
MainController.js
var MainController = ['$scope','$location','appData',
function($scope, $location, appData){
console.log(resolvedData);
}
];
However, the result was exactly the same. Does this have something to do with angular 1.2.5 ?
Here is a working version from someone else
http://mhevery.github.io/angular-phonecat/app/#/phones
And here is the code:
function PhoneListCtrl($scope, phones) {
$scope.phones = phones;
$scope.orderProp = 'age';
}
PhoneListCtrl.resolve = {
phones: function(Phone) {
return Phone.query();
},
delay: function($q, $defer) {
var delay = $q.defer();
$defer(delay.resolve, 1000);
return delay.promise;
}
}
angular.module('phonecat', ['phonecatFilters', 'phonecatServices', 'phonecatDirectives']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/phones', {templateUrl: 'partials/phone-list.html', controller: PhoneListCtrl, resolve: PhoneListCtrl.resolve}).
otherwise({redirectTo: '/phones'});
}]);
Here's an example of the code I've used in the application I'm working on, not sure it will help much because its not much different than how you have it already.
Routing
.when('/view/proposal/:id',{
controller : 'viewProposalCtrl',
templateURL : 'tmpls/get/proposal/view',
resolve : viewProposalCtrl.resolveViewProposal
})
Controller
var viewProposalCtrl = angular.module('proposal.controllers')
.controller('viewProposalCtrl',['$scope','contacts','details','rationale',
function($scope,contacts,details,rationale){
$scope.contacts = contacts;
$scope.details = details;
$scope.rationale = rationale;
// [ REST OF CONTROLLER CODE ]
});
// proposalSrv is a factory service
viewProposalCtrl.resolveViewProposal = {
contacts : ['$route','proposalSrv',function($route,proposalSrv){
return proposalSrv.get('Contacts',$route.current.params.id)
.then(function(data){
return data.data.contacts;
},function(){
return [];
});
}],
details : ['$route','proposalSrv',function($route,proposalSrv){
return proposalSrv.get('Details',$route.current.params.id)
.then(function(data){
return data.data.details;
},function(){
return {};
});
}],
rationale : ['$route','proposalSrv',function($route,proposalSrv){
return proposalSrv.get('Rationale',$route.current.params.id)
.then(function(data){
return data.data.rationale;
},function(){
return {};
]
}]
};
Now that I think about it, when I was developing my application I did have a problem and not sure why when I named my resolve function "resolve." This gave me a problem:
.when('/path',{
// stuff here
resolve : myCtrlr.resolve
})
but this did not:
.when('/path',{
//stuff here
resolve : myCtrlr.myResolveFn
})
Another Possibility
The only other thing I can think of, is that you're returning the promise from the $http call and then trying to use appData.data Try using the .then function or one of the other functions (.success,.error) to retrieve the information from the promise.
The problem was NOT due to previously using different version of AngularJS.
Here are the fixes using the code that I have above.
In app.js, you need to declare the controller as controller: 'MainController' and NOT as controller: MainController even though you have var MainController = app.controller('MainController', ....).
Second and biggest thing was that in my index.html I declared my controller already like so:
index.html
body ng-app="HEY" controller="MainController" /body
This was causing the whole Unknown provider error Apparently angular wont tell you that you have already declared the controller that you are using to do the resolve it and that that will cause a weird error that have nothing to do with the resolve.
I hope this helps someone who may have the same problem.
One thing I noticed in angular 1x docs is that YOU DO NOT SPECIFY THE RESOLVED PARAMETER AS AN ANNOTATED DEPENDENCY
So this:
.when('/somewhere', {
template: '<some-component></some-component>',
resolve: {
resolvedFromRouter: () => someService.fetch()
}
})
export default [
'$scope',
'someService',
'resolvedFromRouter'
Controller
]
function Controller($scope, someService, resolvedFromRouter) {
// <= unknown provider "resolvedFromRouter"
}
is wrong. You don't specify the resolved parameter as a dependency, in the docs:
For easier access to the resolved dependencies from the template, the resolve map will be available on the scope of the route, under $resolve (by default) or a custom name specified by the resolveAs property (see below). This can be particularly useful, when working with components as route templates.
So just do this instead:
.when('/somewhere', {
template: '<some-component></some-component>',
resolve: {
resolvedFromRouter: () => someService.fetch()
}
})
export default [
'$scope',
'someService',
Controller
]
function Controller($scope, someService) {
$scope.$resolve.resolvedFromRouter; // <= injected here
}