AngularJS - unknown provider $modal when getting a service from angular.injector - angularjs

I have a piece of javascript code which needs to call an angular service. I try to access the service by retrieving the angular module where the service is defined and then getting the service it self:
var messagemanagerModule = angular.injector(['ng', 'portal.services.messagemanager']);
var messageService = messagemanagerModule.get('MessageService');
messageService.postMessage('portal', moduleId, 'selectModule');
The module and service is defined like this:
angular.module('portal.services.messagemanager', ['modules.modal', 'modules.softlogoff'])
.factory('MessageService', messageService);
messageService.$inject = ['$rootScope', '$modal', '$translate', 'ConfigurationService'];
function messageService($rootScope, $modal, $translate, ConfigurationService) {
var service = {
showMessage: showMessage,
showSoftLogoff: showSoftLogoff,
postMessage: postMessage,
supportedMessages: supportedMessages
};
return service;
Unfortunately I get the error:
Error: $injector:unpr Unknown provider: $modalProvider <- $modal <- MessageService"
I think I need to inject $modal, but I don't know how to do it.

The ui-bootstrap library now uses `$uibModal' service.
So you need to inject $uibModal service.
messageService.$inject = ['$rootScope', '$uibModal', '$translate', 'ConfigurationService'];
function messageService($rootScope, $uibModal , $translate, ConfigurationService) {
var service = {
showMessage: showMessage,
showSoftLogoff: showSoftLogoff,
postMessage: postMessage,
supportedMessages: supportedMessages
};
return service;

I think you need to include the ui.bootstrap module as a dependency of your module:
include ui.bootstrap in you dependencies:
angular.module('portal.services.messagemanager', ['modules.modal','modules.softlogoff','ui.bootstrap'])
Further you need to include the ui-bootstrap-xxx.min.js somewhere in your html.
If you use ui-bootstrap in version >= 0.14 you need to change $modal to $uibModal

Related

Unknown provider error when injecting AngularJS factory into controller

I'm trying to inject my factory into my controller and I'm getting this error from AngularJS:
Error: $injector:unpr Unknown Provider
I have looked through almost all of the questions on here and still cannot find a solution to my problem. I believe my controller and factory and declared correctly and the injection is correct but it looks like this isn't the case.
My factory code is as follows:
var app = angular.module('test', []);
app.factory('processingFactory', function () {
var factory = {};
factory.newTest = function() {
console.log("TEST");
}
return factory;
});
This is then injected into the controller which looks like this:
angular.module("test", ["angularModalService", "anguFixedHeaderTable",
'angular-loading-bar', "ngResource", "agGrid",
'ui.tree']).controller("dashboardController", [
"$scope",
"$timeout",
"$http",
"$window",
"$interval",
"$resource",
"ModalService",
"$filter",
'$q',
'processingFactory',
function($scope, $timeout, $http, $window, $interval, $resource,
ModalService, $filter, $q, processingFactory) {
//other code removed
$scope.newWorkorder = processingFactory.newWorkorder;
}
]);
This function is called through a button click on the web page. All of the files needed are in script tags on this html page. I am fairly new to angular so this could be a simple error or something I am not aware of.
Calling angular.module with an array as the second argument declares a module, which can only happen for any given module name. You are declaring the module twice (once in your controller code, and again in your factory code).
Try changing the first part of your factory code to:
var app = angular.module('test');
If you are doing the same thing elsewhere in the app you will need to remove the second argument there too, so that there is only one module declaration in the whole app.
if there are any dependencies for your module "test" why do not you have them declared in the first line itself like:
var app = angular.module("test", ["angularModalService", "anguFixedHeaderTable",
'angular-loading-bar', "ngResource", "agGrid",
'ui.tree']);
Then declare your controller like::
app.controler(...)
Things should work fine.

provider not found for underscore

i have an angularjs factory to which i am injecting underscore and application is working fine but when i try to write jasmine test cases on it i am getting an error underscore provider is not found
i have my factory like
angular.module("sample")
.factory("example", example);
example.$inject = ["$document", "$compile", "$rootScope", "$timeout", "$q", "underscore"];
function example($document, $compile, $rootScope, $timeout, $q, _) {
}
and i have my module defined as
(function(){
angular.module(samlple,[]);
})();
and my test case is as
beforeEach(module('sample'));
beforeEach(module('ionic'));
beforeEach(inject(function ($document, $compile, $rootScope, $timeout,underscore,example) {
}
its giving error
Error: [$injector:unpr] Unknown provider: underscoreProvider <- underscore
Add import underscore in your index.html, then add it as a service.
var underscore = angular.module('underscore', []);
underscore.factory('_', function() {
return window._; // assumes underscore has already been loaded on the page
});
And
//Now we can inject underscoreJS in the controllers
function MainCtrl($scope, _) {
//using underscoreJS method
_.max([1,2,3,4]); //It will return 4, which is the maximum value in the array
}
But I recommend you to use lodash! It has more cool functions. Information about how to use lodash with Angular you can find here .
Piggybacking on #Bakhtier's answer, I used the following to get Karma/Jasmine to recognize lodash so I could use it in my services, as well as the rest of my app.
angular.module('app', ['app.services', 'lodash']);
angular.module('app.services', ['lodash']).factory('MyService', ['_', function (_){
// your code bits
}]);
angular.module('lodash', []).factory('_', function() {
return window._;
});
Hope that helps someone out.

using angular.injector with ngAnimate

I have included "ngAnimate" as a dependency to my ngApp.
Now in a jQuery file, I am trying to access this using :
angular.injector(['ng', 'angular-sm']).invoke(['$compile', '$timeout' ,function ($compile, $timeout) {
But this gives me an error of
Error: $injector:unpr
Unknown Provider
Unknown provider: $rootElementProvider <- $rootElement <- $animate <- $compile
And then I changed this to :
angular.injector(['ng','ngAnimate', 'angular-sm']).invoke(['$compile', '$timeout' ,function ($compile, $timeout) {
angular.injector(['ng','ngAnimate', 'angular-sm']).invoke(['$animate','$compile', '$timeout' ,function ($animate,$compile, $timeout) {
And these DIDN'T work either.
Then I tried:
var app_element = document.querySelector('[ng-app=angular-sm]');
angular.element(app_element).injector().invoke(['$compile', '$timeout' ,function($compile,$timeout) {
i.e I took the injector of the ngApp defined and it worked. Why so ?
There is only one $injector in an Angular application, and you can get it using
angular.injector('rootModule')
or
angular.element(document).injector()
In your case it wasn't the root module so you had an error.

Injecting $http into angular factory($exceptionHandler) results in a Circular dependency

When I try inject $http into an overridden factory I get the error:
Uncaught Error: [$injector:cdep] Circular dependency found: $http <-
$exceptionHandler <- $rootScope
AngularModule.factory('$exceptionHandler', function ($http) {
any ideas how to resolve? if I inject using [], $http is undefined
edit__________________
as per an answer below I tried:
MyModule.config(function($provide, $http) {
$provide.decorator("$exceptionHandler", function($delegate) {
return function(exception, cause) {..
but I still get the circular error:
Uncaught Error: [$injector:cdep] Circular dependency found: $http <-
$exceptionHandler <- $rootScope
Inject the $injector and then get the $http service from there. Something like this:
AngularModule.factory('$exceptionHandler', function ($injector) {
var $http = $injector.get("$http");
See https://groups.google.com/forum/#!topic/angular/lbFY_14ZtnU/discussion
However, this will completely override the $exceptionHandler functionality provided by Angular. If you just want to add the server-side log to the existing functionality, see this question about augmenting $exceptionHandler functionality.
I'm using this solution, because of circular dependency issues with rootScope:
angular
.module('facilityLog')
.provider('$exceptionHandler', function() {
"use strict";
this.$get = function($injector) {
function exceptionHandler(exception, cause) {
// This is the part where you get the instance of $http in your case
var $rootScope = $injector.get('$rootScope');
//...
}
return exceptionHandler;
}});
So if you request the instance inside the exceptionHandler-Function you will not get the circular dependency-error.
I used the following to solve this. Note how the array notation is used to make this minification safe.
Note also, that I am completely overriding the $esceptionHandler and using my own service to replace it.
angular
.module('app')
.factory('$exceptionHandler', $exceptionHandler);
$exceptionHandler.$inject = ['$injector', 'exceptionLoggingService'];
function $exceptionHandler($injector, exceptionLoggingService)
{
return function(exception, cause)
{
exceptionLoggingService.http = exceptionLoggingService.http || $injector.get('$http');
exceptionLoggingService.error(exception, cause);
};
}

Service Injection Error on Liferay Portlet

I have develop a Liferay portlet and using AngularJS for the slient side. By using service injection such as $scope in controller will produce an error of the following:-
Error: Unknown provider: aProvider <- a
Example code:-
<script>
function PayrollCalcCtrl($scope){
}
</script>
If $scope is removed, no error will occur. Any workaround to avoid this situation.
Your JS optimizer/obfuscator is messing with your dependencies.
Take a look at the DI docs.
You'll want to define your controller in $inject or inline annotation:
var MyController = function(myScope) {
...
}
MyController.$inject = ['$scope'];
or
app.controller('MyCtrl', ['$scope', function($scope) {
...;
}]);

Resources