I've recently created a new project using AngularJS and ES6. This is my first ES6 project, and I'm very satisfied with it's import statements. Previously I had to use AngularJS dependancy injection in order to use different services in my applications' logic. Now I can easily import different services using ES6 import. The question is that am I allowed to write non-angular services and import them using import
, or I must write them in angular service (or factory) format, and use dependency injection to import?
Hopefully this gives you an insight into using ES6 to write AngularJS apps. AngularJS 2.0 is being written completely using ES6 and as web developers we need to be aware of the way we have to write our code in the near future.
Dependency Injection is pervasive throughout AngularJS. You can use it when defining components or when providing run and config blocks for a module.
It relieves a component from locating the dependency and makes dependencies configurable. It also helps in making components reusable, maintainable and testable. AngularJS provides a supreme Dependency Injection mechanism. It provides following core components which can be injected into each other as dependencies.
Dependency injection, or DI, is one of the fundamental concepts in Angular. DI is wired into the Angular framework and allows classes with Angular decorators, such as Components, Directives, Pipes, and Injectables, to configure dependencies that they need.
First of all, Angular dependency injection and ES6 import are 2 different concepts.
Angular dependency injection is a way to provide components with their dependencies instead of hard coding them within the component. This relieves a component from locating the dependency and makes dependencies configurable.
ES6 import is a javascript feature which is used to import bindings which are exported by another module.
You can import a module, which can be your service class and add it as an angular service. If you are writing a 'non-angular' service, just make sure it is exportable ES6 class. You cannot directly use an ES6 class as a dependency because angular needs to angular-ify it before DI.
my-service.service.js
export default class MyService {
constructor() {
this.items = [''];
}
getItem() {
return this.items;
}
}
MyService.$inject = ['SomeOtherService'];
in index.js
import angular from 'angular';
import MyService from './my-service.service';
angular.module('myApp')
.service('MyService', MyService);
This is one way which ES6 can work with AngularJS dependency injection.
Personally, I eventually have started to only use DI to inject internal services like $http AND singleton application (business-logic) services, which are few.
If I need class, that I want to instantiate (new Something(...)) by myself, then I use es6 module import syntax and pure es6 classes. And across my application these type of classes are majority.
That's it, works perfectly fine. I must say that I've come to this workflow because IDE autocompletion didn't work properly with DI approach, and it started to annoy me very much. Now I enjoy absolutely awesome, correct and superfast autocompletion.
Angularjs dependencies (particularly factories) were a life-savers in before-es6-imports era, because it isolated namespaces for you. Now es6 modules do this. You still benefit from DI, though, because it is only convenient way to use Angular's internal services (e.g. $http) and it is convenient way to instantiate singleton classes (with .service(...)).
UPD. If you want to use angularjs dependencies in your classes outside angularjs, you may use this:
$http = injector('$http')
Injector function comes from here:
// injector.js
let cache = {}
/**
* Use example:
* import injector from 'injector.js'
* $http = injector('$http')
*
* @param dependency {string}
*/
export function injector (dependency) {
return cache.hasOwnProperty(dependency)
? cache[dependency]
: cache[dependency] = angular.element(document).injector().get(dependency)
}
Important! injector() function must run only after document is ready. Usually this is the case, but if not, you will get error "Cannot read property 'get' of undefined" in injector (injector.js). Solution is simply injecting after document is ready:
import { injector } from '../injector.js'
let $http;
angular.element(document).ready(() => {
$http = injector('$http')
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With