Typescript controller inheritance leading to Error: $injector:unpr Unknown Provider due to minification

LATEST UPDATE: 2019/07/16

The issue I am facing is actually a result of misusing $inject. Instead of declaring it as private $inject in api-service.ts, it should have been public static $inject = [...]. During the minification process, explicit injection is crucial but using private $inject made it implicit.


I encountered a similar problem to this post. Instead of the unknown tProvider, my error message specified the provider name as:

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

Both api-service and baseDI-service are named and registered services within the same module.

This is how my module is structured:

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

I imported api-service and other services into baseDI-service, which serves as a service container to avoid passing numerous parameters in super() of component A, for example.

Within component A, the code looks like this:

...
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;
        ...
    }

Upon Grunt Uglify minification, the error shifted to 'Unknown provider: serviceAProvider <- serviceA'. It worked fine without minification.

Prior to this approach, I also attempted to use $injector in the same manner as baseDI-service in controller A to pass it to super(), and in BaseController I utilized $injector.get('api-service'), resulting in the same issue only during minification.

If anyone can explain why both methods failed during Uglify minified mode and provide a solution, I would greatly appreciate it. Minification is necessary in my case.

Furthermore, is utilizing controller inheritance considered a good practice in AngularJS?

Answer №1

To avoid facing issues when minifying your code, consider implementing Strict Dependency Injection.

According to the documentation:

Implementing Strict Dependency Injection

By adding the ng-strict-di directive alongside ng-app, you can activate 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 will generate an error if a service attempts to utilize implicit annotations.

For further details, refer to

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Troubleshooting problems encountered when duplicating an array in JavaScript

I am attempting to utilize properties and flatmap to modify an array without altering the original data. I have implemented this method in two different instances within a single dispatch call in Vue.js when transferring data from parent to children comp ...

Having trouble converting from JavaScript to TypeScript, encountered an error in the process

Seeking assistance with transitioning JavaScript code to TypeScript. const profiles = [{ name: "kamal", age: "20", designation: "developer", grade: "A", }, { name: "arun", age: "25", designation: "developer", grade: ...

problems encountered when testing azure containerclient.listblobsbyhierarchy using sinon

I have developed a REST endpoint with the code "/files/lookup", which is designed to receive a query parameter folderPath and return a list of files with details, excluding content but including metadata. The endpoint connects to Azure Blob Stora ...

Dynamically loading pages into a div with the power of AngularJS

I am attempting to dynamically load pages into a div using a select Here is my HTML code : <div ng-app="App" ng-controller="ProjectCtrl"> <div> <select ng-model="selectedType" class="form-control" ng-change="showContent()" ng-opt ...

WebStorm is not implementing the exclude option as specified in the tsconfig.json file

Is there a way to exclude a directory from TypeScript compilation in WebStorm? Despite specifying the exclusion in the tsconfig.json file, it seems that WebStorm doesn't respect the setting and compiles everything in the root directory. However, runn ...

ng-init is utilized to initiate a function at the conclusion of an AngularJS controller

Is there a way to pass the user's name and ID from a PHP login page to an AngularJS controller when the page loads? I attempted to use ng-init to call basicDetails(username, id). However, this function is triggered at the end of the main controller. A ...

How can I access properties of generic types in TypeScript?

Converting the generic type to any is a valid approach (The type E could be a typescript type, class, or interface) of various entities like Product, Post, Todo, Customer, etc.: function test<E>(o:E):string { return (o as any)['property' ...

Jest snapshot tests are not passing due to consistent output caused by ANSI escape codes

After creating custom jest matchers, I decided to test them using snapshot testing. Surprisingly, the tests passed on my local Windows environment but failed in the CI on Linux. Strangely enough, the output for the failing tests was identical. Determined ...

When a user clicks, they will be directed to the specific product page using Angular UI router

On my homepage, I have a JSON feed where all the products are displayed. When clicking on a specific product image, I want it to redirect to a separate page showing only that particular product. I understand that changes need to be made in the singleproduc ...

When using the e.target.getAttribute() method in React, custom attributes may not be successfully retrieved

I am struggling with handling custom attributes in my changeHandler function. Unfortunately, React does not seem to acknowledge the custom "data-index" attribute. All other standard attributes (such as name, label, etc.) work fine. What could be the issu ...

Utilizing the URL path name for data retrieval in Next.js 14 - A step-by-step guide

I'm currently developing a blog using AWS Amplify Gen 2 and GraphQL for a Next.js 14 project with TypeScript. As part of my application, I need to fetch specific data based on the URL path name. Here's how I've approached it: My approach in ...

Use the protractor to navigate both upwards and downwards

Issue: Timeout occurred after 3005ms I implemented window.scrollTo(0,200) to scroll down the webpage. Below is the code snippet: browser.wait(function() { browser.executeScript('window.scrollTo(0,200);').then(function () { } ...

How to compare and filter items from two arrays using TypeScript

I am looking to filter out certain elements from an array in TypeScript Original Array: [ {"Id":"3","DisplayName":"Fax"}, {"Id":"1","DisplayName":"Home"}, {"Id":&quo ...

Typescript allows you to apply a filter to an array

Query: Is there a way to display a pre-selected item from my dropdown using its unique ID? Issue/Explanation: The dropdown options in my web service are dynamically fetched based on a user's ZipCode. For example, a Provider is displayed as {Pho ...

Encountering an issue: Integrating JSON data into HTML using Angular.JS!

Having trouble transferring JSON data to HTML using Angular.JS for a programming course. The author doesn't seem to have this issue, can anyone provide some assistance? I've correctly linked Angular and added the app, but it's not working a ...

The primary origin of TypeScript is derived from the compiled JavaScript and its corresponding source map

Being new to sourcemaps and typescript, I am faced with a project that has been compiled into a single javascript file from multiple typescript files. The files available to me are: lib.js (the compiled js code of the project) lib.js.map (the source map ...

The default behavior of Angular-Keycloak does not include automatically attaching the bearer token to my http requests

I'm currently working on integrating keycloak-angular into my project, but I'm facing an issue with setting the bearer token as the default for my HTTP requests. "keycloak-angular": "9.1.0" "keycloak-js": "16.0 ...

What is the best way to connect a toArray function to an interface property?

Consider the following scenario: interface D { bar: string } interface B { C: Record<string, D> // ... additional properties here } const example: B = { C: { greeting: { bar: "hi" } } // ... additional properties here } Now I would like t ...

The readline interface in Node that echoes each character multiple times

After creating a node readline interface for my project, I encountered an unusual issue. this.io = readline.createInterface({ input: process.stdin, output: process.stdout, completer:(line:string) => { //adapted from Node docs ...

Automating the scrolling function in Angular 2 to automatically navigate to the bottom of the page whenever a message is sent or opened

In my message conversation section, I want to ensure that the scroll is always at the bottom. When the page is reopened, the last message should be displayed first. HTML: <ul> <li *ngFor="let reply of message_show.messages"> ...