1

UPDATE 2019/07/16

My issue is actually caused by the inappropriate use of $inject. I used it as private $inject in api-service.ts but it should be public static $inject = [...]. When uglifying, it relies on the explicit injection but private $inject made it implicit


I have a very much the same issue with this post. Instead of the tProvider unknown, my error message has the specific provider name but look like

Unknown provider: eProvider <- e <- api-service <- baseDI-service

where api-service and baseDI-service are named and registered services for the same module.

My module looks like as below:

module
--api-service
--other-services
--baseDI-service
--componentA
----controllerA extends BaseController
--componentB
----controllerB extends BaseController

I import api-service and other services in baseDI-service which I used as a service container because I don't want to pass a lot parameters in super() of componentA, for example.

So in componentA it looks like:

...
class ComponentAController extends BaseController {
    public static $inject = ['baseDI-service', ...];

    constructor(baseDIService: BaseDIService) {
        ...
        super(baseDIService); 
        ...
    }
}

BaseDIService.ts:

export default class BaseControllerDIService {
    public static $inject = ['api-service', '$http', ...];
    constructor(
        private apiSvc: ApiService,
        private $http: ng.IHttpService,
        ...
    ) {}

    public getBaseClassDependencies() {
        return{
            apiService: this.apiSvc,
            $http : this.$http
            ... : ...
        };
    }
}

BaseController.ts

export default class BaseController implements ng.IComponentController {    
    apiService: ApiService;
    $http: ng.IHttpService;

    constructor(
        baseDIService: BaseDIService
    ) {
        const services = baseDIService.getBaseClassDependencies();
        this.$http = services.$http;        
        this.apiSvc = services.apiService;
        ...
        this.otherService = services.otherServices;
        ...
    }

After Grunt Uglify minification, the error was like Unknown provider: serviceAProvider <- serviceA. Without minification, everything alright.

Prior to this way, I also tried using $injector the same way as baseDI-service in controllerA to pass it to super(), and in BaseController I use $injector.get('api-service'), I got the same issue with minification only.

Could anyone tell why both way I tried failed in Uglify minified mode, and how can sort it out? I do need minification by the way.

Also, is it a good practice using controller inheritance for AngularJS?

3
  • Hi @georgeawg, if I pass the constructor parameters to BaseController through derived controllers, I still need $inject to state the required parameters again? Commented Jul 15, 2019 at 22:52
  • 1
    The problem is with the dependency injection for the api-service. Make sure that it has a proper $inject property. Show us the code for that service. Commented Jul 15, 2019 at 23:35
  • You just made a correct point and it did help me figure out the issue! Many thanks! Commented Jul 16, 2019 at 3:52

1 Answer 1

2

To help you find this kind of problem before you uglify, use Strict Dependency Injection.

From the Docs:

Using Strict Dependency Injection

You can add an ng-strict-di directive on the same element as ng-app to opt into strict DI mode:

<!doctype html>
<html ng-app="myApp" ng-strict-di>
<body>
  I can add: {{ 1 + 2 }}.
  <script src="angular.js"></script>
</body>
</html>

Strict mode throws an error whenever a service tries to use implicit annotations.

For more information, see

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks very much georgeawg. I tried ng-strict-di it didn't throw any error though. The point is your suggestion actually indicated me to check if there's any implicit injection and I found I wrote private $inject = [...] in api-service and I think this is where disaster started. I changed it to public static $inject = ... and uglified it, now it works!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.