Tips for accessing the 'this' context of the Class in a TypeScript Angular 1.4 directive

Recently, I encountered a problem while using bindToController in my angular directives. Specifically, I was struggling to access properties of the class MultiSelect within my controller method. In this context, 'this' refers to the $scope due to the controllerAs syntax. However, I also needed to figure out how to access my searchService service.

/// <reference path="../../../../definitions/app.d.ts" />
module App.directives
{
    'use strict';

    class MultiSelect implements ng.IDirective 
    {
        restrict = 'E';
        templateUrl = 'directives/multi-select/multi-select.directive.html';
        scope = {};
        bindToController = {
            value: '='
        };
        controllerAs = 'multiSelect';

        constructor(private searchService: App.ISearchService) {

        }

        controller() 
        {
            console.log(this)
            // prints {value: undefined}
            // which matches bindToController

            this.searchService.get();
            // TypeError: Cannot read property 'get' of undefined
        }

        link = ($scope: ng.IScope, element: ng.IAugmentedJQuery, attrs: ng.IAttributes) => {


        }

        static factory(): ng.IDirectiveFactory 
        {
            const directive = (searchService: App.ISearchService) => new MultiSelect(searchService);
            return directive;
        }
    }

    angular.module('App').directive('multiSelect', ['searchService', MultiSelect.factory()]);
}

Answer №1

Lately, I've been experimenting with incorporating bindToController into my angular directives.

However, I've decided against it. It alters the semantics of this in a way that doesn't align with TypeScript's inference.

Answer №2

Here is the implementation as explained by Dan Wahlin. You can find more details about it in the Angular in 20 Typescript project.

///<reference path="../../../tools/typings/tsd.d.ts" />
///<reference path="../../../tools/typings/typescriptApp.d.ts" />

module demoApp.directives {

    class FilterTextbox implements ng.IDirective {

        static instance() : ng.IDirective {
            return new FilterTextbox();
        }

        template = 'Search: <input type="text" ng-model="vm.filter" /> {{ vm.message }}';
        restrict = 'E';
        scope = {
            filter: '='
        };
        controller: ($scope: ng.IScope) => void;
        controllerAs = 'vm';
        bindToController = true;

        constructor() {
            this.controller = function ($scope: ng.IScope) {
                var vm = this;
                vm.message = 'Hello';

                $scope.$watch('vm.filter', (newVal, oldVal) => {
                    if (oldVal !== '' && newVal === '') {
                        vm.message = 'Please enter a value';
                    } else {
                        vm.message = '';
                    }
                });
            };
        }
    }

    angular.module('demoApp').directive('filterTextbox', FilterTextbox.instance);

}

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

Array method involving variable type alterations

Is this a TypeScript bug or am I missing something? Variable type changes based on whether it's in an array method or not. This causes type issues and the only workaround I can think of is an additional typecast in a function call. const fn = (arg: st ...

Describing this as a function parameter/return type in Typescript

I am looking to create a function that can reference the current object's type in its parameter and return types, like so: inside .d.ts: interface Object { add(object: Partial<this>): this; } within .js: Object.prototype.add = function(obj ...

issue with ng-tags-input functionality

Has anyone encountered issues with ng-Input-tags in an angular project? I'm facing a problem where my autocomplete does not update with the searched results. Although my method is returning the correct results, they are not appearing in the dropdown o ...

Trouble with importing a package using path aliases in a Monorepo setup with Lerna and TypeScript

My current challenge involves setting up a TypeScript based monorepo using Lerna. In this setup, I have two packages named bar and foo. The issue arises when foo tries to import bar using a path alias and encounters an error. tree . ├── lerna.json ...

Using Http requests in Angular JS to make requests to a service and retrieve data

While developing my web application using AngularJS, I have always relied on controllers to handle HTTP requests. This approach has made things easier and clearer for me. However, in order to improve the code structure and enhance the execution of my appl ...

Potential absence of the object has been detected after performing object verification

I encountered an issue with the following error message: Object is possibly 'undefined'.ts(2532) This is what my configuration looks like: export interface IDataColumns { name: string; label: string; display: string; empty: boolean; fi ...

Implementing Dependent Props in React using Typescript

I have created a custom Button React Component: function Button({ text, Icon, iconProps, ...buttonProps }: ButtonProps) The properties for this component must adhere to the following rules: Only contain a text Only include an Icon An Icon along with icon ...

Using React and TailwindCSS to create interactive hover effects on elements within the Document Object Model

When hovering over a container, an icon appears. Currently, it is positioned relative to ensure it stays within the container. However, this positioning affects the vertical alignment of other items in the container. Using negative margins as a workaround ...

Is there a way to optimize Typescript compiler to avoid checking full classes and improve performance?

After experiencing slow Typescript compilation times, I decided to utilize generateTrace from https://github.com/microsoft/TypeScript/pull/40063 The trace revealed that a significant amount of time was spent comparing intricate classes with their subclass ...

What type of design pattern does this belong to?

Today, as I was exploring a TypeScript repository, I noticed that all the classes were structured in a particular way: export class ServiceClass { private static instance: ServiceClass; private constructor() {} public static Instance(): ServiceClas ...

Problem with the datepicker in mgcrea.ngStrap

Encountering an issue with the datepicker feature from the mgcrea.ngStrap library. Here is a glimpse of my layout file setup: <html lang="en-US" ng-app="ftc"> <head> <script src="/assets/2db3448a/components/angular.js/angular.min.js">&l ...

Angular is notifying that an unused expression was found where it was expecting an assignment or function call

Currently, I am working on creating a registration form in Angular. My goal is to verify if the User's username exists and then assign that value to the object if it is not null. loadData(data: User) { data.username && (this.registrationD ...

Angular JS unit test for if else statements

I am looking to enhance the code coverage of the branch section by conducting unit tests on the if else statement. However, I am unsure about what exactly needs to be tested in the following code snippet. Controller.js (function () { "use strict"; ...

Can TypeScript support the use of typed streams?

When working with TypeScript and using the typings from @types/node, streams default to using the any type. While this may suffice in most cases, it is not the most optimal approach as data emitted through the data event typically has a consistent type, es ...

Steps for automatically closing a TextPrompt if the end user does not respond within a specific time frame

How can I programmatically close a Prompt in Microsoft Chatbot SDK v4, such as TextPrompt or ConfirmPrompt, and end the dialog after a certain period of time if the user does not reply? I attempted to use setTimeout and step.endDialog but encountered issu ...

The error "Property 'user' does not exist on type 'Session'." occurred while attempting to pass session data using express-session and accessing req.session.user

I'm currently working on creating a basic login form for users to access a website, where I plan to store their session data in a session cookie. The express-session documentation provides the following example for setting it up: app.post('/login ...

Using form input fields to pass AngularJS variables is ineffective

I have a situation where I need to pass confidential data from a parent domain to an iFrame on a different domain that I control. In order to securely transfer this data without using query strings or URLs, I have opted to use Form hidden input fields. Whi ...

tips on using quotes in ng-class directive template

I am facing an issue with using ng-class in a directive template due to too many quotes. Specifically, I want to apply the 'btn-default' class but the quotes are causing problems. Here's the code snippet: template: "<div ng-class='{" ...

What is the best way to retrieve the number of records from a returned object in $resource

Utilizing angular-resource for fetching data from the server, below is the code snippet: var app = angular.module('app',[...]); app.factory('propertiesService', ['$resource', 'CONSTANTS', function($resource, C ...

Creating an array in TypeScript is a versatile and powerful feature that

While I have some familiarity with TypeScript, there is one thing that continues to intrigue me. I understand the distinction between Array<string> and string[]. I am aware that these declarations can be used interchangeably, such as: export class S ...