Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to use with angular? #285

Open
ralyodio opened this issue Jun 15, 2014 · 2 comments
Open

how to use with angular? #285

ralyodio opened this issue Jun 15, 2014 · 2 comments

Comments

@ralyodio
Copy link

I"m currently loading lodash using yeoman includes like this:

<!-- build:js(app) scripts/vendor.js -->
<!-- bower:js -->
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/angular/angular.js"></script>
...
<script src="bower_components/lodash/dist/lodash.compat.js"></script>
<!-- endbower -->
<!-- endbuild -->

How would I include your library as a mixin such that I can do _.capitalize()?

@Oblongmana
Copy link

@chovy Bit late to this party, but I noticed this issue while looking for a solution to a different one! Hopefully you've found a solution by now, but in case anyone else needs this in future, or I forget myself:

One possible solution that follows angular idioms, for the most part:

In the app I'm currently working on (much the same setup - yo angular, added lodash), I like to have 3rd party libs available for dependency injection, instead of just using $window, or a global symbol.

As such, I've imported lodash like so:

//Before the definition of my app's module, add 'lodash' as a model, 
// providing the injectable '_' service
angular.module('lodash',[]).factory('_', function ($window) {return $window._;});

...

// My app module definition - depends on the 'lodash' module
angular.module('myAppName', [...,'lodash',...]]);

...

// A service in my app - depends on the '_' service (provided by 
// the lodash module we set up above)
angular.module('myAppName').factory('myService', function (_) { 
    //example of using the lodash service we injected
    var rangeOfFour = _.range(4);
    ...
 });

So extending that concept, if you want to use underscore.string as a mixin to lodash (instead of as its own injectable service), you can do the mixin when you set up the lodash service. You do this in much the same way you would in a non-angular project (see https://github.com/epeli/underscore.string/blob/master/README.markdown#string-functions)

So we'd rewrite the definition of the lodash module above as follows:

//Before the definition of my app's module, add 'lodash' as a model, 
// providing the injectable '_' service, to which we'll mixin 'underscore.string' functions
angular.module('lodash',[]).factory('_', function ($window) {
  //Mixin underscore.string into lodash
  $window._.mixin($window._.string.exports());
  return $window._;
});

So now the service in my app in the example above can use string functions right off the underscore dependency, so for example, extending the above:

// A service in my app - depends on the '_' service (provided by 
// the lodash module we set up above, and to which we mixed in
// the udnerscore.string functions)
angular.module('myAppName').factory('myService', function (_) { 
    //example of using the lodash service we injected
    var rangeOfFour = _.range(4);
    //example of using an underscore.string function we mixed in
    var capitaliseWord = _.capitalize('word'); //='WORD'
    ...
 });

Related issue you might run into

Improper bower.json on underscore.string

While the current HEAD of underscore.string includes a bower.json - the latest tagged release DOESN'T. As such, the underscore.string you'll find when you do bower install underscore.string doesn't include the main property that signals where to find the actual underscore.string code.

I ran into a problem where the setup created by yo angular therefore couldn't automatically add underscore.string, as grunt-wiredep (the thing that plugs in all of your bower js into your index.html) couldn't find the main property, so didn't know how to inject underscore.string.

The solution to that is to add the following to your project's bower.json, which will signal to grunt-wiredep where it can find underscore.string:

"overrides": {
    "underscore.string": {
      "main": "lib/underscore.string.js"
    }
  }

Karma doesn't like you deleting things from window

Only an issue if you use karma, and you should

The way karma testing operates - the new modules you defined above are re-instantiated every time a karma spec runs, but the scripts are injected into the page only once.

This is a problem - we deleted lodash off $window the first time the module is instantiated, but the lodash library is not injected into the page next time the lodash module is instantiated, so lodash can't return lodash, because it can't get it off $window anr more, because we deleted last time we instantiated the module.

I got around this by changing the pattern for nabbing stuff off window slightly. I still don't want $window polluted, so I added a _thirdParty property to window, where we move any third party libs when we try to load a module. so the new pattern looks like this (I've used lodashService instead of _ here so it remains readable):

angular.module('lodash',[]).factory('lodashService', function ($window) {
  if($window.lodashService){
    $window._thirdParty = $window._thirdParty || {};
    $window._thirdParty.lodashService = $window.lodashService;
    try { delete $window.lodashService; } catch (e) {$window.lodashService = undefined; /*<IE8 doesn't do delete of window vars*/}
  }
  var lodashService = $window._thirdParty.lodashService;
  return lodashService;
});

@adnanmamajiwala
Copy link

Is there a way to use this library with angular 2 ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants