Trying to built a modal with angularjs and ui-bootstrap:
Version
Angularjs and its component is 1.5.3
ui-bootstrap-tpls-1.3.3.js.
In main app file I have included 'ui.bootstrap' as
var App = angular.module('aotaApp', ['ui.router','ui.bootstrap','checklist-model','ngSanitize'])
.controller("myController", function($scope,$state, $http)
In StatusService I am using this as
App.service("StatusModalService", ["$uibModal",
function ($uibModal) {
var modalDefaults = {
backdrop: true,
keyboard: true,
modalFade: true,
templateUrl: 'resources/template/modal/confirmationModal.html'
};
var modalOptions = {
closeButtonText: 'Close',
actionButtonText: 'OK',
headerText: 'Proceed?',
bodyText: 'Perform this action?'
};
this.showModal = function (customModalDefaults, customModalOptions) {
if (!customModalDefaults) customModalDefaults = {};
customModalDefaults.backdrop = 'static';
return this.show(customModalDefaults, customModalOptions);
};
this.show = function (customModalDefaults, customModalOptions) {
//Create temp objects to work with since we're in a singleton service
var tempModalDefaults = {};
var tempModalOptions = {};
//Map angular-ui modal custom defaults to modal defaults defined in service
angular.extend(tempModalDefaults, modalDefaults, customModalDefaults);
//Map modal.html $scope custom properties to defaults defined in service
angular.extend(tempModalOptions, modalOptions, customModalOptions);
if (!tempModalDefaults.controller) {
tempModalDefaults.controller = function ($scope, $uibModalInstance) {
$scope.modalOptions = tempModalOptions;
$scope.modalOptions.ok = function (result) {
$uibModalInstance.close(result);
};
$scope.modalOptions.close = function (result) {
$uibModalInstance.dismiss('cancel');
};
}
}
return $uibModal.open(tempModalDefaults).result;
};
}]);
But I am getting error
angular-1.5.3.js:13424 Error: [$injector:unpr] Unknown provider:
$uibModalProvider <- $uibModal <- StatusModalService
I am new to angular and mainly found to add ui.bootstrap in app. but it's not giving any help.
Please guide me.
It seems like a version issue, Need to upgrade your ui-bootstrap
https://github.com/compact/angular-bootstrap-lightbox/issues/42
Install latest version of angular-bootstrap
npm install angular-bootstrap or bower install angular-bootstrap
This could also be due to a renaming of $uibModal. If you have this error, try using $modal instead.
Related
I am trying to implements a modal from this answer but I fail to use the service in the app controller. The question is simple: How can I use the modalService via injection in the emaApp main controller?
modal.js
angular.module('emaApp', []).service('modalService', [ '$modal',
// NB: For Angular-bootstrap 0.14.0 or later, use $uibModal above instead of $modal
function($modal) {
var modalDefaults = {
backdrop : true,
keyboard : true,
modalFade : true,
templateUrl : '/app/partials/modal.html'
};
var modalOptions = {
closeButtonText : 'Close',
actionButtonText : 'OK',
headerText : 'Proceed?',
bodyText : 'Perform this action?'
};
this.showModal = function(customModalDefaults, customModalOptions) {
if (!customModalDefaults)
customModalDefaults = {};
customModalDefaults.backdrop = 'static';
return this.show(customModalDefaults, customModalOptions);
};
this.show = function(customModalDefaults, customModalOptions) {
//Create temp objects to work with since we're in a singleton service
var tempModalDefaults = {};
var tempModalOptions = {};
//Map angular-ui modal custom defaults to modal defaults defined in service
angular.extend(tempModalDefaults, modalDefaults, customModalDefaults);
//Map modal.html $scope custom properties to defaults defined in service
angular.extend(tempModalOptions, modalOptions, customModalOptions);
if (!tempModalDefaults.controller) {
tempModalDefaults.controller = function($scope, $modalInstance) {
$scope.modalOptions = tempModalOptions;
$scope.modalOptions.ok = function(result) {
$modalInstance.close(result);
};
$scope.modalOptions.close = function(result) {
$modalInstance.dismiss('cancel');
};
};
}
return $modal.open(tempModalDefaults).result;
};
} ]);
index.js
var app = angular.module('emaApp', []);
app.controller('mainCtrl',['$scope', '$http', 'modalService', function($scope, $http, modalService) {
$scope.deleteModel = function(modelId) {
var modalOptions = {
closeButtonText : 'Cancel',
actionButtonText : 'Delete Customer',
headerText : 'Delete ' + modelId + '?',
bodyText : 'Are you sure you want to delete this model?'
};
modalModule.showModal({}, modalOptions).then(function(result) {
//your-custom-logic
alert("muaha")
});
}
}]);
You are defining module emaApp multiple times. Hence overwriting the existing module, You need to retrieve module in file which is loaded later i.e. index.js, notice removed []
var app = angular.module('emaApp');
instead of
var app = angular.module('emaApp', []);
You already injected the service into your controller. You should use modalService instead of -possibly- undefined modalModule in your controller.
This is my LoginController, as you can see I have injected the LoginService, I can't seem to figure out why I am getting the error mentioned above (Note: I've made the project modular by breaking my project in separates folder, using gulp and browserify to bundle everything into one file)
'use strict';
function LoginController($scope, $ionicModal, $timeout, $location,
$ionicLoading, $ionicPopup, LoginService) {
// With the new view caching in Ionic, Controllers are only called
// when they are recreated or on app start, instead of every page change.
// To listen for when this page is active (for example, to refresh data),
// listen for the $ionicView.enter event:
//$scope.$on('$ionicView.enter', function(e) {
//});
// Form data for the login modal
$scope.loginData = {};
// Create the login modal that we will use later
$ionicModal.fromTemplateUrl('js/modules/login/login.html', {
scope: $scope
}).then(function(modal) {
$scope.modal = modal;
});
// Triggered in the login modal to close it
$scope.closeLogin = function() {
$scope.modal.hide();
};
// Open the login modal
$scope.login = function() {
$scope.modal.show();
};
$scope.show = function() {
$ionicLoading.show({
template:'<p>Loading...</p><ion-spinner></ion-spinner>'
});
};
$scope.hide = function(){
$ionicLoading.hide();
};
// Perform the login action when the user submits the login form
$scope.doLogin = function() {
console.log('Doing login', $scope.loginData);
// Start showing the progress
$scope.show($ionicLoading);
// Do the call to a service using $http or directly do the call here
LoginService.login($scope.loginData).success(function(data) {
// Do something on success for example if you are doing a login
console.log('Login successful', data);
}).error(function(data) {
// Do something on error
console.log('Login failed', data);
}).finally(function($ionicLoading) {
// On both cases hide the loading
console.log('Hide');
$scope.hide($ionicLoading);
});
};
}
module.exports = ['$scope', '$ionicModal', '$timeout','$location',
'$ionicLoading','LoginService','$ionicPopup',
LoginController];
This is my LoginService file, this is very weird to me because I've injected the appropriate file but yet I keep getting the error mentioned above. Any help or guidance would deeply be appreciated.
'use strict';
function LoginService($http, $q, API_ENDPOINT) {
var BASE_URL = API_ENDPOINT.url;
var LOCAL_TOKEN_KEY = 'yourTokenKey';
var isAuthenticated = false;
var authToken;
function storeUserCredentials(token) {
window.localStorage.setItem(LOCAL_TOKEN_KEY, token);
useCredentials(token);
}
function useCredentials(token) {
isAuthenticated = true;
authToken = token;
// Set the token as header for your requests!x-access-token'
$http.defaults.headers.common.Authorization = authToken;
}
var login = function(user) {
return $q(function(resolve, reject) {
$http.post(BASE_URL + '/authenticate', user).then(function(result){
if (result.data.success) {
storeUserCredentials(result.data.token);
resolve(result.data.msg);
}else{
reject(result.data.msg);
}
});
});
};
return {
login: login,
isAuthenticated: function() {return isAuthenticated;},
};
}
module.exports = ['$http', '$q', 'API_ENDPOINT', LoginService];
This is my login.js file in the same directory as the one posted above
'use strict';
module.exports = angular.module('login', [])
.factory('LoginService', require('./login-service'))
.controller('LoginController', require('./login-controller'));
You should first do require and then only define the service. Since you are directly passing require in the .factory('LoginServie, require()` the service name is getting registered but its body is empty.
I've not worked much with require but here is you can try:
require('./login-service');
module.exports = angular.module('login', [])
// Make this code synchornous that this should only run when above require loaded the script
.factory('LoginService', LoginService)
.controller('LoginController', require('./login-controller'));
Or (probably)
require('./login-service', function() {
module.exports = angular.module('login', [])
.factory('LoginService', LoginService)
.controller('LoginController', require('./login-controller'));
})
When using a factory you are getting the actual class, and you need to instantiate it. When using a service you get an instance of the service. Take a look at the following example: AngularJS : Factory and Service?
It's been a few weeks with this problem, I'm new to Angular so I hope is an easy fix.
I'm using Angular Bootstrap Modal (ui.bootstrap.modal) and it's not working. this is my code.
On contentApp.js (with additional config options)
angular
.module('contentApp', [
'ui.bootstrap',
'ui.router',
'satellizer',
'angular-jwt',
'angular.morris-chart'
])
// Additional Configuration...
On TransModalController.js
angular
.module('contentApp')
.controller('TransModalController', TransModalController)
.controller('MICnewGroup', MICnewGroup)
.controller('MICaddTransmitter', MICaddTransmitter);
function TransModalController($scope, $http, $uibModal, $log) {
$scope.openModal = function (url) {
var ModalInstanceController = "";
if ('newGroup' == url) {
url = "php/modal/newGroup.html";
ModalInstanceController = 'MICnewGroup'
} else if ('addTransmitter' == url) {
url = "php/modal/addTransmitter.html";
ModalInstanceController = 'MICaddTransmitter'
};
var modalInstance = $uibModal.open({ //<-- Line 26
animation: true,
templateUrl: url,
controller: ModalInstanceController,
size: 'sm',
resolve: {
user: $scope.sub
}
});
};
}
// Controller for Modal Instance of New Group
function MICnewGroup($scope, $http, $state, $uibModalInstance, user) {
$scope.newGroup = {
'user': user,
'name': ''
}
$scope.createGroup = function() {
$http.post('api/user/'+$scope.sub+'/group', $scope.newGroup)
.then(function(data) {
$state.go($state.current, {}, {reload: true}); //second parameter is for $stateParams
$uibModalInstance.close();
}
);
}
}
// Controller for Modal Instance of Add Transmitter
function MICaddTransmitter($scope, $http, $state, $uibModalInstance, user) {
$scope.newTransmitter = {
'user': user,
'code': ''
}
$scope.addTransmitter = function() {
$http.put('api/transmitter/'+$scope.newTransmitter.code, $scope.newTransmitter)
.then(function(data) {
$state.go($state.current, {}, {reload: true}); //second parameter is for $stateParams
$uibModalInstance.close();
}
);
}
}
All this works fine on my localhost (Mac), but when uploaded to my Server (Ubuntu) throws me this error
angular.js:12477Error: [$injector:unpr] Unknown provider: 3Provider <- 3
http://errors.angularjs.org/1.4.7/$injector/unpr?p0=3Provider%20%3C-%203
at angular.js:68
at angular.js:4289
at Object.getService [as get] (angular.js:4437)
at angular.js:4294
at Object.getService [as get] (angular.js:4437)
at ui-bootstrap-tpls.js:4056
at Object.forEach (angular.js:350)
at getResolvePromises (ui-bootstrap-tpls.js:4052)
at Object.$modal.open (ui-bootstrap-tpls.js:4097)
at Scope.TransModalController.$scope.openModal (TransModalController.js:26)
Angular is v1.4.7, ui.bootstrap is v0.14.3
Why it works on my Localhost but not on my Server?
Most likely due to minification, see the 'A note on minification' section at this link
I have problem related AngularJS dependency injection and timing between them. Here is my code and error
var module = angular.module('Demo', []);
module.factory('demo', function () {
return {
data: {},
};
});
module.provider('foo', ['demo', function(demo) {
console.log(demo);
this.$get = function() {
};
}]);
Error:
Uncaught Error: [$injector:modulerr] Failed to instantiate module Demo due to:
Error: [$injector:unpr] Unknown provider: demo
But if I add setTimeout on last definition everything works fine, but its hacking code it shouldn't be like this.
var module = angular.module('Demo', []);
module.factory('demo', function () {
return {
data: {},
};
});
setTimeout(function(){
module.provider('foo', ['demo', function(demo) {
console.log(demo);
this.$get = function() {
};
}]);
});
Here is problem on fiddle:
http://jsfiddle.net/zcf7rb4s/1/
You cannot add demo as a dependency there because it does not yet exist. That's the way the $injector works. What you can do is list demo as a dependency in the $get function of the provider. That's going to be executed by the $injector after all providers have been defined.
Check this:
<div ng-app="Demo">
<div ng-controller="test">{{x}}</div>
</div>
And the definitions:
var module = angular.module('Demo', []);
module.factory('demo', function () {
return {
data: {x: 'x'},
};
});
module.provider('foo', function() {
this.$get = function(demo) {
return {
demo: demo
};
};
});
module.controller('test', ['$scope', 'foo', function($scope, foo) {
$scope.x = foo.demo.data.x;
}]);
The code inside the factory and provider is run at "step 1".
Then, in "step 2" AngularJS binds the controller. It first uses $injector to inject the dependencies (that have been previously defined in "step 1"). So in practice your $timeout "emulates" this behavior, that's why it works. But it's wrong, that's not the way you are supposed to use them.
Inject into the provider like this instead:
module.provider('foo', function() {
this.$get = ['demo', function(demo) {
console.log(demo);
}];
});
I'm still a debutant on Angularjs.
I want to inject dynamically a dependency of a service (that I created) in my controller.
But when I code a service with dependencies, I got this error :
Error: Unknown provider: $windowProvider <- $window <- base64
This is the code of the controller.
var base64 = angular.injector(['servicesModule']).get('base64');
console.log("base64", base64.encode("my text will be encoded"));
This code works:
var servicesModule = angular.module('servicesModule', []);
servicesModule.factory('base64', function() {
return {
name: 'base64',
readonly: false,
encode: function(input) {
return window.btoa(input);
},
decode: function(input) {
return window.atob(input);
}
};
});
This code doesn't work :
var extModule = angular.module('ext', []);
extModule.factory('base64', ['$window', function($window) {
return {
name: 'base64',
readonly: false,
encode: function(input) {
return $window.btoa(input);
},
decode: function(input) {
return $window.atob(input);
}
};
}]);
Another problem is when the service is in the same module as the controller.
If the module has dependencies, I doesn't work (I have $routeProvider dependence in my module config) :
Error: Unknown provider: $routeProvider from mainModule
var mainModule = angular.module('main', [],
function($routeProvider, $locationProvider) {
//Some routing code
}
);
JS Fiddles
Same module with dependencies(controller + service) : http://jsfiddle.net/yrezgui/YedT2/
Different module with dependencies : http://jsfiddle.net/yrezgui/YedT2/4/
Different module without dependencies : http://jsfiddle.net/yrezgui/YedT2/5/
Don't call angular.injector() -- this creates a new injector. Instead, inject the already-created $injector into your controller and use it:
So instead of:
var algoController = function($scope) {
$scope.base64 = angular.injector(['main']).get('base64');
};
Do this:
var algoController = function($scope, $injector) {
$scope.base64 = $injector.get('base64');
};
But most of the time you should inject your service directly, rather than dynamically, like so:
var algoController = function($scope, base64) {
$scope.base64 = base64;
};
See also AngularJS dynamically inject scope or controller