inject jquery and underscore to angular js component

All we need is an easy explanation of the problem, so here it is.

I am using angularjs, underscore and jQuery in my new service:

myModule.factory('MyService', ['MyResource', function (MyResource) {
     ....
    // Here I make use of _ and $
}]);

How can I inject underscore or jQuery to the new service so I can be sure that _ is underscore and $ is jquery?

I am looking for something like:

myModule.factory('MyService', [ 'underscore', 'jquery','MyResource', function (_, $, MyResource) {
     ....
    // Here I want to use $ and _ and be SURE that _ is underscore and $ is jquery
}]);

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

based on @moderndegree’s approach I have implemented the following code, I cannot say it is perfect but this way tester would know if it has jQuery dependency as $window is too generic object to inject.

'use strict';
(function () {
    var app= angular.module('app');
    //these are just references the instance of related lib so we can inject them to the controllers/services in an angular way.
    app.factory('jQuery', [
        '$window',
        function ($window) {
            return $window.jQuery;
        }
    ]);

    app.factory('Modernizr', [
        '$window',
        function ($window) {
            return $window.Modernizr;
        }
    ]);

    app.factory('Highcharts', [
    '$window',
    function ($window) {
        return $window.Highcharts;
    }
    ]);

})();

Method 2

If you include jQuery and Underscore in your HTML, they will be globally available. There is no need to “inject” them.

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script src="//documentcloud.github.io/underscore/underscore-min.js"></script>

If you wanted to include them in a module, you could do something like this:

angular.module('myApp', []).
service('vendorService', ['$q', '$timeout', '$window', function($q, $timeout, $window){
    var deferred = $q.defer(), libs = {};
    $script([
        '//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js',
        '//documentcloud.github.io/underscore/underscore-min.js'
    ], 'vendorBundle');
    $script.ready('vendorBundle', function() {
        libs.$ = $window.jQuery.noConflict();
        libs._ = $window._.noConflict();
        $timeout(function(){
            deferred.resolve(libs);
        }, 0);
    });
    this.getLibs = function(){
        return deferred.promise;
    }
}]).
controller('myController', ['$scope', 'vendorService', function($scope, vendorService){
    vendorService.getLibs().then(function(libs){
        $scope.jQueryVersion = libs.$.fn.jquery;
        $scope._ = libs._;
    });
}]);

Doing this will allow you to load the libraries asynchronously while keeping them from conflicting with previously loaded versions. There may be a better way to store references to the loaded libraries but this should work just fine.

Also, this example relies on a third party laoder ($script.js).

And here is a jsFiddle (http://jsfiddle.net/moderndegree/bzXGx/);

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply