danny libren
danny libren

Reputation: 137

importing angular services with ES6 and webpack

I'm trying to import $timeout with ES6 and webpack and I keep getting that $timeout is undefined. Can anyone help? If there's a way that doesn't involve using $inject I'd prefer it because I'm gradually trying to get rid of angularjs in my code.

randomTVNames.service.js:

import angular from 'angular';

class RandomTVNames {
    constructor($timeout) {
        this.tv = ['Shield', 'Walking Dead', 'Castle', 'Leftovers'];
        this.timeout = $timeout;
        console.log(this.timeout);
    }

    getName() {
        const totalNames = this.tv.length;
        const rand = Math.floor(Math.random() * totalNames);
        return this.tv[rand];
    }

    getTimeout(){

        this.timeout(function () {
            alert("this is timeout")}, 3000);
    }
}

RandomTVNames.$inject = ['$timeout'];

//todo - try to inject angular argument (such as $timeout) with $inject
var randomTVNames = new RandomTVNames();

export default randomTVNames;

home.controller.js:

import randomTVNames from '../../services/randomTVNames.service';
import mainModule from '../../mainModule';

class HomeController {
    constructor() {
        this.tv = randomTVNames;
        this.name = 'World';
    }

    randomTVName($timeout) {
        this.name = this.tv.getName();
    }

    getCtrlTimeout(){
        this.tv.getTimeout();
    }

}

mainModule.controller('HomeController', HomeController);

Upvotes: 1

Views: 3903

Answers (3)

Egor Litvinchuk
Egor Litvinchuk

Reputation: 1870

please take a look at this loader. it helps with what you're trying to do. but mind adding 'ngInject' anywhere in your js file, that injects anything

Upvotes: 0

user4872511
user4872511

Reputation:

ES6 modules are not compatible with the module system from Angular 1.x. This means that exporting and importing services and controllers won't work, you need to register and inject them using Angular's module system.

randomTVNames.service.js:

import mainModule from '../../mainModule';

class RandomTVNames {
    // ... snip ...
}

RandomTVNames.$inject = [ /* ... snip ... */ ];

mainModule.service('randomTVNames', RandomTVNames);

home.controller.js:

import mainModule from '../../mainModule';

class HomeController {
    constructor($scope, randomTVNames) {
        this.$scope = $scope;
        this.tv = randomTVNames;
    }
}

HomeController.$inject = ['$scope', 'randomTVNames'];

mainModule.controller('HomeController', HomeController);

Then in your main webpack file, make sure to import both of them so they get bundled:

import 'services/randomTVNames.service';
import 'controllers/controller.service';

Upvotes: 2

Tomer
Tomer

Reputation: 17930

There is no way to get rid of $inject, unless you are not minifying you code (but i hope you are).

Angular is injecting variables using their names, so when it sees $scope, it know to look for it and inject it, but when minifying your code the variable names are changed ($scope becomes c etc.) and angular does not know what object you want to inject.

That is what $inject is for since strings are not minified.

Upvotes: 0

Related Questions