Having difficulties injecting a Service into a TypeScript Controller

I recently started working with TypeScript and I created a controller where I need to inject a service in order to use its methods. However, I am facing an issue where I am unable to access the service functions and encountering an error.

Error

TypeError: _this.marketingService.getAllActiveItems is not a function
    at ExportController.getRealCustomerInfo (exportCtrl.js:20)
    at $parseFunctionCall (angular-1.3.js:12475)
    at callback (angular-1.3.js:21703)
    at ChildScope.$eval (angular-1.3.js:14571)
    at ChildScope.$apply (angular-1.3.js:14670)
    at HTMLInputElement.<anonymous> (angular-1.3.js:21708)
    at HTMLInputElement.dispatch (jquery.min.js:14)
    at HTMLInputElement.a.handle (jquery.min.js:14)

Controller

module Marketing.GetRealExportCtrl {

    import IStateParamsService = ng.ui.IStateParamsService;
    import IFlashService = Flash.Services.IFlashService;

    class ExportController {

        listFilters: any;
        fileterExport: any;
        currentValue: string;
        filterValueSelected: string;
        listNumber: number;
        reports: ICustomerInfo[];

        static $inject = ['$stateParams', 'marketingService', '$scope'];

        constructor(private marketingService: IMarketingService) {

            this.listFilters = [
                {
                    name: 'All',
                    listNumber: 1
                },
                {
                    name: 'All PCs',
                    listNumber: 2
                },
                {
                    name: 'All BPs',
                    listNumber: 3
                }];

            this.fileterExport = this.listFilters[0];
            this.listNumber = this.listFilters[0];
        }

        changeFilter = (): void => {
            this.listNumber = this.fileterExport.listNumber;
        }

        getRealCustomerInfo = () => {
            this.marketingService.getRealCustomerInfo(this.listNumber)
                .then((reports: ICustomerInfo[]) => {
                    this.reports = reports;
                }, function (err) {
                    var e = err;
                  console.log(e);
               });

        }
    }

    angular
        .module('Marketing')
        .controller('ExportController', ExportController);
} 

My Marketing Service

module Marketing.MarketingService {
    import IAjaxService = Common.IAjaxService;
    import AjaxServiceOptions = Common.ajaxService.AjaxServiceOptions;
    import IAjaxResponse = Common.IAjaxResponse;


    class MarketingService implements IMarketingService {
        constructor(
            private ajaxService: IAjaxService,
            private $translate: ng.translate.ITranslateService,
            private $q: ng.IQService) {
            this.$q = $q;
        }
        getRealCustomerInfo = (listNumber: number): ng.IPromise<ICustomerInfo[]> => {
            return this.ajaxService.makeAdminCall('marketingApi', 'getRealCustomerInfo', new AjaxServiceOptions({
                cache: false,
                defaultErrorMessage: 'Loading Customers failed'
            })).then((result: IAjaxResponse) => {
                if (result.data.isSuccessful)
                    return result.data.data;
            });
        }
    }

    service.$inject = ['ajaxService', '$translate', '$q'];

    function service(ajaxService, $translate, $q) {
        return new MarketingService(ajaxService, $translate, $q);
    }

    angular
        .module('Marketing')
        .service('marketingService', service);
}

Interface

declare module Marketing {
    export interface ICustomerInfo {
        CustomerID: number;
        CustomerName: string;
        Phone: string;
        Phone2: string;
        MobilePhone: string;
        Email: string;
        MainAddress1: string;
        CustomerTypeID: number;
        CustomerTypeDescription: string;
        SponsorID: number;
        SponsorName: string;
        EnrollerID: number;
        EnrollerName: string;
        PriceTypeID: number;
        PriceTypeDescription: string
    }
    export interface IMarketingService {

        getRealCustomerInfo: (listNumber: number) => ng.IPromise<ICustomerInfo[]>;
    }
}

It appears that the

this.marketingService.getRealCustomerInfo(this.listNumber)
function is not being recognized in the controller. I have been stuck on this issue for days now, without any clue as to why it's happening. Any help would be greatly appreciated, thank you in advance.

Answer №1

The issue seems to be related to the dependency injection in the ExportController.

You have specified

static $inject = ['$stateParams', 'marketingService', '$scope'];

however, your constructor looks like this

constructor(private marketingService: IMarketingService) { ... }

It appears that the variable marketingService is being assigned the value of the first dependency $stateParams (which does not contain the desired function).

To resolve this issue, you can either remove any unused dependencies from your $inject statement or adjust your constructor to match the injections.

A helpful hint:

In the MarketingService,

constructor(
    private ajaxService: IAjaxService,
    private $translate: ng.translate.ITranslateService,
    private $q: ng.IQService) {
    this.$q = $q;
}

There is no need for this.$q = $q;. By specifying an access modifier on a constructor parameter, it will automatically be bound to the class (more information here).

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

Youngster listens for guardian's occurrence in Angular 2

While the Angular documentation covers how to listen for child events from parents, my situation is actually the opposite. In my application, I have an 'admin.component' that serves as the layout view for the admin page, including elements such a ...

Which free and publicly accessible JSON image API is available for testing JSON requests?

Recently, I've been experimenting with AngularJS and am eager to incorporate some images using free APIs. While exploring options, I came across Flickr but was discouraged by the registration requirement for app usage. I am seeking a more accessible s ...

Incorporate an Ajax response script with a Django HttpResponse

How can I pass the ajax response obtained from the view to the template using HttpResponse? I'm unsure of the process. view.py analyzer = SentimentIntensityAnalyzer() def index(request): return render(request, "gui/index.html") @csrf_exempt d ...

Tips for displaying numbers in thousands, millions, or billions in vue.js

For example: 12000 can be shown as 12k, 1000000 as 1m, and 1430 as 1.4k. <div v-for="item in items" :key="item"> <span>{{item.num}}</span> </div> <script lang='ts'> items:any[]=[ {num:"122256879"}, ...

The absence of CORS headers detected in XMLHttpRequest

I am currently trying to execute an ajax call to a remote server, only for developmental purposes. I have configured CORS on my server, which is why when I request the resource through the browser, it shows that the CORS headers are present. https://i.sta ...

Transferring user-selected values from JavaScript to a PHP file

When sending values from JavaScript to a PHP file, everything works smoothly when all the values are collected. Step1 functions perfectly as both fields are mandatory. However, in Step2, values are only sent when all the fields are selected. There are co ...

I am getting NaN as the output from my function, but I am unsure of the reason behind

For pracitce, I have created this code to calculate the total amount spent on gas and food using arrays. However, I am encountering an issue where it is returning NaN. const gas = [20, 40, 100]; const food = [10, 40, 50]; function total(gas, food) { ...

Angular 14 now offers ngx-pinch-zoom for an enhanced zooming experience

Is it possible to add ngx-pinch-zoom to an Angular 14 project? I encountered a peer dependency conflict when trying to install pinch-zoom with --legacy-peer-deps, which worked in the project but failed in the ci/cd pipeline due to the conflict. I attempt ...

Showcase a sizable picture broken down into smaller sections

I am interested in creating a mapping application similar to Google Maps that can asynchronously load images from the backend. I am seeking guidance on where to begin and how to proceed in this endeavor. The ultimate goal is to have the image displayed w ...

AngularJS - Establishing communication between controller and view

I am facing an issue with the Angularjs view. I seem to be making a mistake somewhere and I can't figure out where the problem lies. I hope someone can assist me with this. The problem is that {{user.login}} (userRepoInfo.html file) is not being call ...

Focus on selecting each label within a table using JavaScript

In my current setup, I am attempting to customize radio buttons and checkboxes. Array.from(document.querySelectorAll("tr")).forEach((tr,index)=>{ var mark=document.createElement("span"); Array.from(tr.querySelectorAll("input")).forEach((inp,index ...

What is the best way to redirect a user to a different URL in Express while also sending additional data along with the request

[NODE, express] Developing a Facebook application where user grants access and is redirected to my site with a unique code at abc.com/heyBuddy/fb/callback?code="adasdasdasda". Once the code is received in route router.get('/heyBuddy/fb/callback', ...

Tips for customizing the appearance of Material UI's time picker diolog styles

I am currently incorporating the Material UI Time Picker from GitHub, specifically TeamWertarbyte's repository. My task involves modifying the color of the time displayed. In the image provided, I aim to customize the color of the time shown as 11:3 ...

Issue with Refresh Triggering Update, localStorage, useState, useEffect Combination

I want my app to execute the code inside the useEffect hook every 5 seconds, regardless of whether the page is refreshed or not. Currently, the code only runs when the page is refreshed and then remains inactive until the page is refreshed again. It seems ...

Retrieving the Textfield value upon clicking the InputAdornment in Material UI

I need help figuring out how to access the value of a Textfield after clicking on the icon within the InputAdornment. Initially, everything seemed to be working using OnChange, but now I'm receiving an output of undefined <Textfield id="se ...

typescriptExtract generic type from TypedDocumentNode<MyType, unknown> using introspection

I am currently utilizing a library that allows me to retrieve the type from a returned variable within a function. const myVar = gql(somestring) // The library function is called gql type myVarType = typeof myVar // The resultant value of myVarType is Typ ...

Using AngularJS for dynamically generated HTML elements that have not been loaded into the DOM involves creating an AngularJS directive that manages

Hey there! I'm a newcomer to AngularJs and I'm currently fetching HTML data from C# through an ajax call. I'm attempting to incorporate AngularJs functionality for the dynamically generated HTML, but unfortunately I'm not seeing any Ang ...

Update the content of the widget

Currently, I am utilizing the following script to display NBA standings: <script type="text/javascript" src="https://widgets.sports-reference.com/wg.fcgi?script=bbr_standings&amp;params=bbr_standings_conf:E,bbr_standings_css:1&amp"></sc ...

Is there a way to showcase just the month in one spot when presenting data using Angular 13?

Just starting out with Angular and facing a challenge in the Milestone section. There is a loop for displaying years and months, but I need to ensure that the month name is displayed only once for each specific year. Can someone provide me with a possible ...

When using Typescript, the keyof operator for objects may not undergo refinement and can result in error

I've been working on creating a function that validates whether a key in an object is a non-empty string. export const validateRequiredString = <T>( obj: T, key: keyof T & (string | number) ): void => { if (typeof obj[key] !== " ...