Use underscore inside Angular controllers
Solution 1
When you include Underscore, it attaches itself to the window
object, and so is available globally.
So you can use it from Angular code as-is.
You can also wrap it up in a service or a factory, if you'd like it to be injected:
var underscore = angular.module('underscore', []);
underscore.factory('_', ['$window', function($window) {
return $window._; // assumes underscore has already been loaded on the page
}]);
And then you can ask for the _
in your app's module:
// Declare it as a dependency of your module
var app = angular.module('app', ['underscore']);
// And then inject it where you need it
app.controller('Ctrl', function($scope, _) {
// do stuff
});
Solution 2
I have implemented @satchmorun's suggestion here: https://github.com/andresesfm/angular-underscore-module
To use it:
-
Make sure you have included underscore.js in your project
<script src="bower_components/underscore/underscore.js">
-
Get it:
bower install angular-underscore-module
-
Add angular-underscore-module.js to your main file (index.html)
<script src="bower_components/angular-underscore-module/angular-underscore-module.js"></script>
-
Add the module as a dependency in your App definition
var myapp = angular.module('MyApp', ['underscore'])
-
To use, add as an injected dependency to your Controller/Service and it is ready to use
angular.module('MyApp').controller('MyCtrl', function ($scope, _) { ... //Use underscore _.each(...); ...
Solution 3
I use this:
var myapp = angular.module('myApp', [])
// allow DI for use in controllers, unit tests
.constant('_', window._)
// use in views, ng-repeat="x in _.range(3)"
.run(function ($rootScope) {
$rootScope._ = window._;
});
See https://github.com/angular/angular.js/wiki/Understanding-Dependency-Injection about halfway for some more info on run
.
Solution 4
You can also take a look at this module for angular
https://github.com/floydsoft/angular-underscore
Solution 5
If you don't mind using lodash try out https://github.com/rockabox/ng-lodash it wraps lodash completely so it is the only dependency and you don't need to load any other script files such as lodash.
Lodash is completely off of the window scope and no "hoping" that it's been loaded prior to your module.
Pablo
Updated on October 30, 2020Comments
-
Pablo over 3 years
How do I use underscore library inside angularjs controllers?
On this post: AngularJS limitTo by last 2 records somebody suggested to assign an _ variable to the rootScope so that the library will be available to all the scopes within the app.
But I'm not clear where to do it. I mean should it go on the app module declaration? i.e:
var myapp = angular.module('offersApp', []) .config(['$rootScope', function($rootScope) { }
But then where do I load underscore lib? I just have on my index page the ng-app directive and script reference to both the angular-js and underscore libs?
index.html
:<head> </head> <body ng-app="offersApp"> ... <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <script src="scripts/vendor/angular.js"></script> <script src="scripts/vendor/underscore.js"></script> ...
How do I achieve this?
-
Walter Stabosz about 11 yearsI don't understand why you would inject it when it is already in the global window scope.
-
fess . almost 11 yearsProbably for the same reasons you inject anything, instead of putting everything in the global scope. However, since you're a lot less likely to want to substitute out your underscore library during testing than some other more specific dependency it's understandable that it doesn't seem necessary.
-
Shanimal almost 11 yearsits necessary when you add 'use strict' to your file. Since underscore/lodash isn't defined it will throw ReferenceError: _ is not defined... you have to inject it, or use window._
-
Aditya M P almost 11 yearsHa! I wanted to do the injecting because it's cool, thanks for giving me a real reason, @Shanimal.
-
sunwukung almost 11 yearsyou might also want to inject _ for the sake of testing. How would you go about bringing the underscore dependency into a test suite environment
-
zakdances over 10 yearsCouldn't you also just do
var _ = window._;
at the top of your controller? -
holographic-principle over 10 years@Shanimal that's not true. It works by just accessing _ (as a global) in strict mode as well.
-
Michal Charemza over 10 yearsAngular already provides $window that can be injected into controllers, which is just a reference to the global window object. Then you can access $window._ in the controller, without accessing the global scope directly.
-
Jan Molak over 10 yearsI agree with @MichalCharemza, try to avoid using global window object in your service. The above example rewritten to use $window would look more or less like this:
angular.module('underscore', []);
angular.module('underscore').factory('_', ['$window', function ($window) { return $window._; }]);
-
chovy almost 10 yearshow do you load this thing in a controller?
-
chovy almost 10 yearsDoes not appear to work. I get an undefined error:
Uncaught ReferenceError: _ is not defined
-
unify almost 10 yearsI added the clarification: you need to include underscore.js. This connector only helps you to use it in a service. See @satchmorun's answer
-
Nate over 9 yearsthis looks good but do you have an example? I need to change all uppercase to upper on first character only using _.capitalize()
-
wires over 9 yearsI think this should work
<p>{{ _.capitalize('lalala') }}</p>
? -
Mark Amery over 9 years@Shanimal despite its many upvotes, your comment is nonsense;
"use strict";
prevents globals from being implicitly declared, by assigning to a name that hasn't been declared withvar
or otherwise created in a visible scope. It does not require you to access existing, declared globals aswindow
properties. You can simply access them as variables, which they are.window
itself is a global variable, for goodness' sake; if what you were saying were true, all globals would be strictly inaccessible by any means whatsoever. -
wires over 9 years@LVarayut I don't know, why not try it? (I have since moved to ReactJS)
-
Michał Miszczyszyn about 9 yearsYou should use
$window
instead ofwindow.
-
Tim Hong almost 9 yearsPlease use service instead. Avoid adding stuff to your $rootScope will help you to have better performance.
-
Luke almost 9 yearsI would think that underscore is more of a service than a factory (based on this stackoverflow.com/a/21900284/1766230) Why use
factory
instead ofservice
? -
Trevor almost 8 yearsI always worry about modules that haven't been updated for years
-
Paul Preibisch over 7 yearscan you please provide usage instructions
-
Olivvv about 7 yearsNot sure what I did wrong but I could not get the "use in views" part to work. But passing the service to the controller and then to the tpl through $ctrl works.