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

Steps to transfer the content of a label when the onclick event occurs

Seeking advice on how to send the dynamically varying value of a label upon clicking an anchor tag. Can anyone recommend the best approach to passing the label value to a JavaScript function when the anchor is clicked? Here is a sample code snippet: < ...

ESLint does not recognize the components used in Element UI

I've been working with Vue.js and Element UI components. However, when I try to use elements like Input or Col, ESLint throws an error with the message invalid-end-tag. I have already added eslint-plugin-vue to my setup, so why isn't ESLint reco ...

Leveraging body-parser for capturing an indefinite amount of text fields in node/express

Background In pursuit of my Free Code Camp back end certification, I am embarking on the task of creating a voting application. For detailed information and user stories required for this project, visit this link: Among the user stories is the ability to ...

Tips for updating the current user's username value in local storage in Angular

https://i.stack.imgur.com/ZA32X.png https://i.stack.imgur.com/iDHZW.png I am facing an issue with updating the local storage of a current User for only username. When I update the username, it's not reflecting in local storage. Even though I can s ...

In the ajax call, an empty JSON array object is sent as the data

Utilizing JSON data as a parameter for an ajax call: var startDate = dateFormatForSave($("#start_date").val().trim()); var arrayOfStudentsInfo = []; var table = $("#selected_students"); table.find('tr').each(function(i, el) { var rowId = $( ...

Updating the model of a Vuejs single file component (.vue) within the <script> tag

Discovering the world of vuejs, I set out to create a basic single file component for testing purposes. This component's main task is to showcase a boolean and a button that toggles the boolean value. It also listens for a "customEvent" which trigger ...

Can a custom directive with dynamic behavior be crafted in AngularJS?

Allow me to begin by explaining my intentions with broken-pseudocode: // controllers.js angular.module('myApp.controllers', []). controller('MyCtrl1', [function() { var template = '<div my-directive></div>' ...

Avoid unintended double-tapping on mobile devices

On my main page, I have a button that triggers an overlay with item details, including buttons like one that reveals a phone number. An issue arises when a user accidentally double-clicks the main page button. The first click is processed on the main page ...

Grab the code snippet from JSFiddle

I apologize for the seemingly simple question, but I have been struggling with it. I tried looking at similar questions, but I couldn't find a solution. Despite copying the code from http://jsfiddle.net/sB49B/21/, I can't seem to get it to work ...

Error message in Angular 2: Unable to locate node module for import

Recently, I encountered an issue while attempting to utilize a specific node module called aws-api-gateway-client Although the installation was successful, I am facing difficulties with importing this module due to an error. Oddly enough, it works seamle ...

The document retrieved through $meteor.object in angular-meteor fails to display/render

I've encountered a strange issue with my angular-meteor program where the $meteor.object method is returning an unexpected object instead of a document. Currently, I'm working on code that closely resembles the tutorial provided by angluar-meteo ...

What steps can I take to fix the Error with webpack's style hot loader JavaScript?

Just starting out with native script and encountered an issue when running this code: <template> <view class="container"> <text class="text-color-primary">My Vue Native Apps</text> </view> </template> &l ...

I'm curious, what is the exact function of ...state?

Just dipping my toes into NgRx (redux) within Angular and I'm a bit puzzled by the use of ...state in the code snippet below. My understanding is that it functions as spread operator, but I can't grasp why the data attributes from the Interface S ...

Storing and retrieving objects in cookies using AngularJS

I'm having trouble retrieving the object I set in a cookie, as it's showing me [Object Object] instead. Here is the code snippet where I SET the object into the cookie: click: function (event, ui) { //other code $scope.fields = {name:true, ima ...

Adjusting the contenteditable feature to place the caret on a specific child node

I am experiencing some challenges when attempting to position the cursor after an <i> tag within a contenteditable element. Currently, this is what I have: <p contenteditable="true"><i>H</i><i>e</i><i>l</i> ...

Pressing the escape key on the keyboard will act as a shortcut to go

Is there a way to use Javascript in a browser to make the escape key on the keyboard go back? For instance, when visiting this page and clicking the "Fullscreen" link, it would be great to simply press the escape key and return to the previous page. What ...

How to mock nested functions within sinon

There are several questions similar to this one, but none of them quite match the scenario I'm dealing with. The situation involves a function that takes another function as a parameter: var myfunc = (func_outer) => { return func_outer().func ...

Issue with saving image in blob field (Integration problem between Angular App and Python)

I am attempting to save an image from my angular App into a mysql blob field using python, however, the image is not saving correctly. This is how I am converting the image to a byte-array: var reader = new FileReader(); reader.readAsArrayBuffer($scope. ...

"Exploring the depths of Webpack's module

This is my first venture into creating an Angular 2 application within MVC Core, utilizing TypeScript 2.2, Angular2, and Webpack. I have been closely following the Angular Documentation, but despite referencing the latest NPM Modules, I encounter errors w ...

Using the debug module, we're able to set up debugging for our Express application with the specific tag "express-locallibrary-tutorial:server". I am curious to understand the purpose and significance of this setup

I've been diving into backend development with Express lately. I decided to work on the express-locallibrary-tutorial project from GitHub. However, I'm having trouble grasping something. var debug = require('debug')('express-locall ...