Reputation: 1546
I want to start using ES6 (2015) in my Angular 1.3 + grunt stack without refactoring the entire existing ES5 code, (or switching grunt with other tool..) But when trying to use a new ES6 service from an "old" controller I'm getting following error,
" Cannot read property '1' of null at Function.annotate [as $$annotate] .... "
The babel configuration in grunt:
babel: {
options: {
sourceMap: true,
presets: ['es2015']
},
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.app %>',
src: '**/*.es6.js',
dest: '.tmp/app',
ext: '.es5.js'
}]
},
test: {
files: [{
expand: true,
cwd: 'test/spec',
src: '{,*/}*.es6.js',
dest: '.tmp/spec',
ext: '.es5.js'
}]
}
},
The service code:
class InfoService {
constructor($http) {
this.$http = $http;
}
getInfo() {
console.log('getting');
return this.$http.get('/backend/something/readAll');
}
}
InfoService.$inject = ['$http'];
angular.module('app').service('Info', $http => InfoService($http));
The use in es5 controller:
angular.module('app').controller('SomeCtrl',
function ComposerCtrl(Info) {
Info.getInfo();
});
The transpiled ES5 InfoService was generated under .tmp/app (and I configured grunt watch to update changes while developing) so I wonder what am I doing wrong..
Upvotes: 0
Views: 452
Reputation: 1546
So I've found a way to make it work but I don't like it so much.. I configured the babel to dist the files at the same place my *.es6.js files and updated the index.html so Angular will load the es5 transpiled file (InfoService.js), and when I debug I do it on the es6 file (I guess it relates to the sourceMap)
babel: {
options: {
sourceMap: true,
presets: ['es2015']
},
dist: {
files: [{
expand: true,
src: '**/*.es6.js',
ext: '.js'
}]
},
Upvotes: 0
Reputation: 4013
You have forgotten about new
:
...
angular.module('app').service('Info', $http => new InfoService($http))
In this case, angular will not benefit from $inject
property and you will need to ng-annotate your code, as it solves to:
angular.module('app').service('Info', function($http) { return new InfoService($http); });
The simpler solution it to replace service definition with:
angular.module('app').service('Info', InfoService);
Angular's DI will use $inject
property and add new
operator for you.
It is worth noting, that TypeScript users had the same problem: How can I define an AngularJS service using a TypeScript class that doesn't pollute the global scope?
EDIT:
It is possible, that you are using wrong controller expression (for example unclosed ng-controller
attribute:
<div .... ng-controller="SignupFormController as signupFormCtrl>
This messes up angular and leads to this error message on older versions of angular (1.3).
More info about issue: https://github.com/angular/angular.js/issues/10875
Upvotes: 1