6

I am writing a browser app, and I have a file that creates an object and initializes it. The app is written in AngularJS, but the file in question is plain Javascript, outside the Angular ecosystem.

I want to use promises in that file, but since Angular contains an an implementation of Q, I'd rather just use that than bring in another library.

I am also using RequireJS.

So, is there a way to use $q in a non-Angular file?

FrontierPsycho
  • 743
  • 7
  • 25

1 Answers1

9

You can do this by using the angular.injector() method which returns an $injector function that can be injected with dependencies that you need (e.g. $http, $q) through its invoke() method.

DEMO

Something like this:

angular.injector(['ng']).invoke(['$q', function($q) {

  $q.when('hello world').then(function(message) {
    window.alert(message);
  });

}]);

Note that the array passed to angular.injector() is a list of modules, I included the ng module because that is where the AngularJS core dependencies are located.

ryeballar
  • 29,658
  • 10
  • 65
  • 74
  • But this way, ``$q`` will use a different ``$rootScope`` as the rest of the app. So using ``$rootScope.$apply()`` on the "normal" ``$rootScope`` (e.g. in unit tests) won't work for that ``$q``, right? – Ignitor Oct 28 '16 at 14:57
  • @Ignitor. That is not necessarily true, the `ng` module is technically added as a dependency for all modules. Therefore the `$rootScope` for the module that you create also shares the `$rootScope` of the `ng` module. As of the writing of this comment, the angular.js version is 1.5.8, you will see that the `ng` module is added as a default module for all modules in the bootstrap process, [**in this line**](https://github.com/angular/angular.js/blob/v1.5.8/src/Angular.js#L1688). Additionally, the native angularjs services, providers, factories and values resides in this module. – ryeballar Oct 29 '16 at 10:51
  • 1
    Just tried it: I saved a reference to the ``$rootScope`` within a controller and compared it to the ``$rootScope`` I've got from this: ``angular.injector(['ng']).invoke(['$rootScope', function($rootScope) { console.dir($rootScope); }])``. They do *not* match and even have different ``$id``s. – Ignitor Oct 31 '16 at 12:17