using angular.injector with ngAnimate - angularjs

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.

Related

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

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

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.

Angular injector error with minified JavaScript

I have been struggling to find a solution for this problem:
I am using Angular.js on my site.
I use CoffeeScript to write my JavaScript in Visual Studios 2012. When I save my CoffeeScript - both a minified and un-minified version of the JavaScript file is saved.
While using any minified version of JavaScript files on my webpage I keep getting this error:
Error: $injector:unpr
Unknown Provider
Unknown provider: nProvider <- n
This error results from the $injector being unable to resolve a required dependency. To fix this, make sure the dependency is defined and spelled correctly. For example:
If I don’t use the minified version everything works fine.
Here is how I use angular to declare my App in each JavaScript file
(function() {
var myApp;
myApp = angular.module("myApp", ['uploaddirective']);
myApp.controller("videoController", function($scope, $http, $compile) {
Can anyone help me to resolve this issue?
Use array notation for minification-safe dependency injection:
myApp.controller("videoController", ['$scope', '$http', '$compile', function($scope, $http, $compile) {
Another option is to use build task to automatically annotate injections for you:
// #ngInject
myApp.controller("videoController", function($scope, $http, $compile) {
You will need grunt or gulp plugin for this, like ngAnnotate.
https://docs.angularjs.org/guide/di
When you minifying the above code you will get something like
a.controller("videoController", function(x, y, z) {...
note that $scope, $http, $compile are replaced with x, y, z.
So when angular starts to execute Controller can't find the injectors because $scope, $http, $compile are replaced with x, y, z and there are no inject-able providers as x, y or z, so angular will trigger a error saying Unknown Provider.
solution 1
you can follow Inline Array Annotation as,
myApp.controller("videoController", ['$scope', '$http', '$compile', function($scope, $http, $compile) {...
after minifying this you will get something like
a.controller("videoController", ['$scope', '$http', '$compile', function(x, y, z) {...
minifying process doesn't effect on strings, here angular will use a array with strings that will match the providers. Here angular will match the x with $scope and so on.
solution 2
$inject Property Annotation
var MyController = function($scope, $http, $compile) {
// controller function ...
}
MyController.$inject = ['$scope', '$http', '$compile'];
myApp.controller("videoController", MyController);
additionally check ng-annotate

Angular controller minification

I have created an app based on ng-boilerplate. All works just fine. However, now I am coming close to deployment, I want to compile and minify the code. This is straighforward enough using grunt compile, but of course the app breaks when minified. I didn't expect anything less!
I have injected dependencies into my controllers like this:
var appCtrl = app.controller('AppCtrl', function AppCtrl($scope, $rootScope, helpService, userService, menuService, $location) {... body ...});
appCtrl.$inject = ['$scope', '$rootScope', 'helpService', 'userService', 'menuService', '$location'];
I have also tried it like this:
var appCtrl = app.controller('AppCtrl', ['$scope', '$rootScope', 'helpService', 'userService', 'menuService', '$location',
function AppCtrl($scope, $rootScope, helpService, userService, menuService, $location) {... body ...}]);
All I ever get is an error like this: Error: Unknown provider: aProvider <- a
I have also looked at my services and injected the dependencies in a similar way to the second method above, but then I started getting errors in the program even when it was not minified. It was telling me $q has no method defer()!
app.factory('checkAuth', ['$q', '$location', '$filter', '$rootScope', function ($q, $location, $filter, $rootScope) {...body...}]);
My question is, what am I missing? Am I doing the dependency injections correctly? Is there somewhere else needing DI?
Thanks!
EDIT:
Just found this: Angular.module minification bug
It hasn't completely fixed the problem... I now get the error:
TypeError: Object #<error> has no method 'slice'
but at least this is away from Error: Unknown provider: aProvider <- a :-)
Your second approach is using angular's inline annotation method, and that should be able to be minified correctly.
Other approaches will not work because of how Angularjs handles it's dependency injection - it will look at the parameter's name to determine the provider. Your minifier will change the parameter name from $scope to a, and Angjuar will try to find a provider for a. The inline style fixes this at the cost of more typing and a bit more maintenence. (There's a tool that will alter your angular code so that it can be minified by grunt here: https://github.com/btford/ngmin )
I would expect that your issue is that not all of your controllers or modules were altered to use the inline style, and you continued to get the error. Make sure you change all of it - read up on Angularjs DI, especially inline annotation.
OK - Fixed it: I changed the filter to return text rather than a boolean value like this:
function orgFilter(item, args) {
if ((args.searchString !== "" && item["strName"].indexOf(args.searchString) == -1) &&
(args.searchString !== "" && item["strShortName"].indexOf(args.searchString) == -1) &&
(args.searchString !== "" && item["strCode"].indexOf(args.searchString) == -1)
) {
// return false;
return 'continue_coreloop';
}
// return true;
return 'add_result';
}
... and then changed the compileFilter() function to match the text
var filterBody = filterInfo.body
.replace(/return \'continue_coreloop\'[;}]/gi, "{ continue _coreloop; }")
.replace(/return \'add_result\'[;}]/gi, "{ _retval[_idx++] = $item$; continue _coreloop; }")
.replace(/return ([^;}]+?);/gi,
"{ if ($1=='add_result') { _retval[_idx++] = $item$; }; continue _coreloop; }");
Uglify doesn't change the text values so the match will still be true.

having issues with angular minification

I'm having an issue with angular minification when I release. I've redone my controller to have annotations as recommended, but still get the same error:
Error: Unknown provider: nProvider <- n
Here's my first few lines of code for the controller:
var app = angular.module('myApp', ['ngGrid', 'ui.bootstrap.dialog']);
app.controller('MyCtrl', ['$scope', '$dialog', '$http', function ($scope, $dialog, $http){
UPDATE: sorry, I found that there was another function I was using which was taking in $scope as parameter. That was causing the issue. I basically did the same thing to annotate its parameters, and now it works.

Resources