Adding Dependencies to a Static Factory in Typescript

I have developed a service in typescript as a Class. Within this class, I have defined a static Factory where dependencies are injected.

However, when I compress my application, the dependencies get compressed too, leading to an undefined provider error.

This is how my service looks like:

export class TInterceptor {    
public static $inject = ['$q', '$rootScope'];
public static Factory($q:ng.IQService, $rootScope:ng.IRootScopeService)
{
  return new TInterceptor($q, $rootScope);
}
constructor(private $q:ng.IQService, private $rootScope:ng.IRootScopeService){}...}

The service is called here:

  angular
    .module('t')
    .config(config);

  function config($httpProvider:ng.IHttpProvider)
  {
    $httpProvider.interceptors.push(TInterceptor.Factory);
  }

My concern is, how can I ensure that the dependencies remain protected from getting overwritten during code compression?

Answer №1

To activate the factory, you must:

angular.module('myapp').factory('interceptorFactory', ['$q','$rootScope',TInterceptor.Factory]);

Add the factory name in the configuration block:

$httpProvider.interceptors.push('interceptorFactory');

You can also use an array instead (as it internally uses `$injector.invoke` and is not a string):

 $httpProvider.interceptors.push(['$q','$rootScope', TInterceptor.Factory]);

Don't forget to explicitly annotate the `config` block as well.

.config(['$httpProvider', config]);

Answer №2

UPDATE: Latest on Typescript 1.6

With the release of Typescript 1.6, supporting class expressions, you can now utilize a class expression with a closure for your injections:

angular.module('myApp')
    .factory('MyFactory', function($q, $http) {

        return class {

            constructor(data) {
                // Access to $q and $http here
            }
        }
    })

Typescript 1.5 Approach

Until version 1.6, Typescript does not allow class expressions. As an interim solution, I use the following syntax:

class MyClass {

    constructor(
        private $q: ng.IQService,
        private $http: ng.IHttpService,
        data) {

    }
}

I then apply the standard Angular factory definition, enabling the use of ng-annotate during build. I curate the class with factory injections before returning it:

angular.module('myApp')
    .factory('MyFactory', function($q, $http) {

        var factory = MyClass

        // Return curried MyClass
        return Function.prototype.bind.apply(factory,
            Array.prototype.concat.apply([factory], arguments))
    });

The return line can be simplified as:

return MyClass.bind(MyClass, $q, $http)

Although less readable, this approach avoids repetition when changing dependencies.

If you have Lodash or Underscore, a more elegant alternative is available:

return _.curry(MyClass).apply(this, arguments)

This enables instantiating the class by providing essential data only:

new MyFactory(data)

Answer №3

There are two ways to define it:

1) Specify it in the config function

function configuration(){...}
configuration.$inject = ['$httpProvider'];

2) Define it while adding your function to the module

angular
  .module('t')
  .config(['$httpProvider', configuration]);

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

Although VSCode is functioning properly, there seems to be a discrepancy between the VSCode and the TS compiler, resulting in an

While developing my project in VSCode, I encountered an issue with accessing req.user.name from the Request object for my Node.js Express application. VSCode was indicating that 'name' does not exist in the 'user' object. To address thi ...

Customizing the Position of Material UI Select in a Theme Override

I'm trying to customize the position of the dropdown menu for select fields in my theme without having to implement it individually on each select element. Here's what I've attempted: createMuiTheme({ overrides: { MuiSelect: { ...

Angular filter that replaces underscores with spaces

Looking for a solution to replace underscores with spaces in a string ...

Issue with CSS transition not displaying ng-show elements properly

I'm currently working on incorporating a fade-in effect for text using the second solution from this source when using ng-show. Here is my HTML setup: <input ng-focus="hasFocus = true" ng-blur="hasFocus = false" type="text" placeholder="Cli ...

Calculating numbers with Math.ceil will result in an increase of 1

After using Math.ceil, one value was rounded up to 50 and the other to 80. However, when I added these two values together, the result unexpectedly turned out to be 131. console.log(Math.ceil(e.currentTarget.clientHeight) // 50 console.log(Math.ceil(e.cu ...

Concluding the use of angular-bootstrap-datetimepicker when selecting a date

I am currently utilizing the UI Bootstrap drop-down component to display the angular-bootstrap-datetimepicker calendar upon clicking. Although it works well for the most part, I have encountered an issue where the calendar block does not close when clicked ...

The function ValueChange remains uninvoked

Query: The issue is that valueChanges is only triggered for the entire form and not for specific controllers. Although this approach works, it returns the complete object. public ngOnInit(): void { this.form.createWagonBodyForm(); ...

The various types of Angular 2 FormBuilders

As I delved into learning Angular 2, I initially came across ngModel, and later discovered FormGroup/FormBuilder which seemed more suitable for handling complex forms. However, one downside that caught my attention was that by using FormBuilder, we sacrifi ...

In what ways does PROJEN streamline project configuration for infrastructure and application projects?

Exploring PROJEN and AWS CDK has raised questions for me regarding how PROJEN contributes to standardizing project configurations in the context of multiple projects or repositories. While I see its usefulness for a single project or repository through the ...

Explore the world of data manipulation in Angular by experimenting with different

Embarking on a fresh Angular 2 project centered around Photos and Users. The backend work is all done, with the API in place. I've already constructed those classes. Now, I find myself pondering... To manipulate these objects on the client end, wo ...

Dynamic URL used in TRPC queries`

Is there a way to query a single post in TRPC and Next JS based on a dynamic url without using SSR or SSG? I have tried adding as string to router.query.id but encountered a TRPC error (only happening during the first load) because router.query.id is ini ...

Converting JSON into an interface in TypeScript and verifying its validity

How can I convert a JSON string to a nested interface type and validate it? Although my model is more complex, here is an example: export interface User = { name: Field; surname: Field; }; export interface Field = { icon: string; text: string; vis ...

Unleashing the power of TypeScript with Solid JS Abstract Class

Why am I getting an undefined error for my calcUtilisation method when using an Abstract Class as the type in createStore? Is there a way to utilize a type for the data along with a method within the same class for createStore? abstract class Account { ...

After upgrading Expo, the React Native Auth Session ceased to function

During my use of Expo SDK 48, my app successfully implemented Google and Facebook authentication with a web browser-based authentication method. Functional code: type AuthResponse = AuthSession.AuthSessionResult & { params: { access_token ...

Is there a way to silence TypeScript's complaints about a React rendered value being converted into a Date object?

In my latest project using Next.js, TypeScript, Prisma, and Radix-UI, I'm working with a loan object that has various key-value pairs: { "id": 25, "borrowerName": "Test Borrower 1", "pipelineStage": ...

Can you retrieve the Angular Service Instance beyond the scope of an angular component?

Is it possible to obtain the reference of an Injectable Angular service within a generic class without including it in the constructor? I am exploring different methods to access the Service reference. For example: export class Utils { getData(): string ...

Extending Two Classes in Typescript: A Complete Guide

I am looking for a way to efficiently save time by reusing common code across classes that extend PIXI classes within a 2D WebGL renderer library. Object Interfaces: module Game.Core { export interface IObject {} export interface IManagedObject e ...

Dexie is alerting us to a problem with a call that occurs before initialization

When setting up my application, I encountered an error related to the Courses Entity Class being called before initialization in my Dexie Database. Despite checking my code, I couldn't find any issues and there was no documentation available for this ...

Set up a personalized React component library with Material-UI integration by installing it as a private NPM package

I have been attempting to install the "Material-UI" library into my own private component library, which is an NPM package built with TypeScript. I have customized some of the MUI components and imported them into another application from my package. Howe ...

Typescript in React is throwing an error that says you cannot destructure the property 'colored' from the 'boxShadows' object because it is undefined

After downloading the material dashboard react theme from an open source GitHub project, I tried to convert the project into Typescript (React + Typescript). However, I encountered the following error (See Attached Image) https://i.stack.imgur.com/YZKpK.p ...