Leveraging TypeScript to call controller functions from a directive in AngularJS using the "controller as"

I've encountered an issue while trying to call a controller function from a directive, specifically dealing with the "this" context problem. The logService becomes inaccessible when the function is triggered by the directive.

Below is the code for the controller:

class MainController implements IMainScope {

        static $inject = ["LogService"];

        constructor(private logService:ILogService) { }

        sayHello(message:string) {
          console.log("MainController sayHello", message);
          // If called from directive, it throws 'Cannot read property 'logService' of undefined'
          this.logService.log(message);
        }
    }

And here's the directive class:

class TestDirective implements ng.IDirective {
        public restrict = "E";
        public templateUrl = "test-directive.html";
        public replace = true;
        public scope:any = {
            testFn: "&"
        };

        constructor() { }

        public link:ng.IDirectiveLinkFn = (scope:TestDirectiveScope, element:ng.IAugmentedJQuery, attrs:ng.IAttributes):void => {
            scope.hello = () => {
              console.log("TestDirective", scope.firstName);
              scope.testFn()(scope.firstName);
            };
        }

        static factory():ng.IDirectiveFactory {
            let directive:ng.IDirectiveFactory = () => new TestDirective();
            return directive;
        }
    }

To illustrate the problem, you can check out this simple plunker example: http://embed.plnkr.co/Ov7crFZkkjDPzilX2BmL/

Answer №1

When calling the testFn function from a directive, it is important to do so correctly. To pass data along with the function call, you should first use:

ng-click="vm.sayHello(message)"

Additionally, when calling the function within the directive, make sure to pass the data in JSON/object format like this: {message: 'some value'} within parentheses.

scope.testFn({message: scope.firstName});

Check out a demo on Plunkr!

Answer №2

When working with callbacks, such as Angular binding, it's important to bind methods to their context. In TypeScript, the recommended approach is to define a method as an arrow function like this:

    greetUser = (userName:string)  => { ... }

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

Issues with using hooks in a remote module in Webpack 5 module federation

I am attempting to create a dynamic system at runtime using Module Federation, a feature in webpack 5. Everything seems to be working well, but I encounter a multitude of 'invalid rule of hooks' errors when I add hooks to the 'producer' ...

Animate the parent container of ng-view in Angular by targeting an element within ng-view

Are you able to use CSS animations to animate a div's background color that is located outside of the ng-view, while using a directive on a $state within the ng-view? The ng-view already has CSS animations for routing. When I try to add animation cl ...

"Troubleshooting the issue of AngularJS $http patch request failing to send

The information is successfully logged in the console when passed to replyMessage, but for some reason, the API does not seem to be receiving the data. Is the input field perhaps empty? replyMessage: function(data) { console.log(data); ...

Using resolve to preload data in Angular's $routeProvider initialization process

I am working on an AngularJS application and need to fetch data from a REST API before the controller initializes. I am using the "resolve" in my routeProvider and have injected the necessary value into the controller to ensure that the data is available. ...

Passing variables from the browser to Protractor can be achieved by utilizing the browser

I am currently in the process of testing a single page application that involves making a GET request to a specific API endpoint and expecting certain results. To facilitate this testing process, I have mocked the API using the $httpbackend object. My mai ...

Create a dynamic animation using Angular to smoothly move a div element across the

I currently have a div with the following content: <div ng-style="{'left': PageMap.ColumnWrap.OverviewPanelLeft + 'px'}"></div> Whenever I press the right key, an event is triggered to change the PageMap.ColumnWrap.Overvie ...

Please explain the significance of `input = input || '' ''` when creating personalized filters in AngularJS

When customizing our own filter, we must provide the data as input for filtering in the filter function. However, within the function I notice this line of code: input = input || ' '. Custom Code Example angular.module('myReverseFilterApp& ...

Tips for utilizing ngModel within *ngFor alongside the index?

Currently, I am dynamically generating mat-inputs using *ngFor. My goal is to store each value of [(ngModel)] in a separate array (not the one used in *ngFor) based on the index of the *ngFor elements. Here's my implementation: <div *ngFor="let i ...

Concealing an input field in AngularJS

I am currently developing a login page with register and login options using AngularJS. The interface includes three input fields: username, password, and name. I aim to display the name field upon clicking the register button and hide it upon clicking t ...

Creating an Escape key press event in plain Typescript without using JQuery

Is there a way to trigger an Escape button press event in Angular unit tests? const event = document.createEvent('UIEvent'); event.initUIEvent('keydown', true, true, window, 0); (<any>event).keyCode = 27; (<any ...

Enforce Immutable Return in TypeScript

Hello, I am curious to know if there is a way to prevent overwriting a type so that it remains immutable at compile time. For example, let's create an interface: interface freeze{ frozen: boolean; } Now, let's define a deep freeze function: f ...

Error! Element not found in cloned iframe #2460, promise unhandled

Can you help me troubleshoot this issue? This is the code I'm working with: const section = document.createElement("section"); const myHTMLCode = "<p>Greetings</p>"; section.insertAdjacentHTML("afterbegin", my ...

"Error encountered while attempting to make the entire row in AngularJS UI-Grid editable simultaneously

I am currently facing an issue while trying to make a whole row editable using ui-grid with AngularJs. If you could take a look at the coding in the provided plnkr link and let me know where I might have gone wrong, that would be really helpful. Click her ...

Using AngularJS to showcase a table generated from a two-dimensional array

I have been exploring ways to showcase a table using a 2D Array. Unfortunately, I am currently unable to generate any output; all I need is a simple boolean value of 1 or 0. Any suggestions would be highly appreciated. var Matrix = [ // array data h ...

Utilize the same controller and view for both searching and non-searching functionality within Angular

Currently, I am developing an Angular application that consists of a single controller and view. I am facing the challenge of wanting to display the same view with or without a search field, based on user preference. My idea is to pass an extra parameter ...

Utilize cypress to analyze the loading time of a webpage

My current challenge involves using cypress to carry out website tests. I am looking for a reliable method to measure the duration it takes for certain cypress commands to load or execute. As an example: //var startTime = SomeStopwatchFunction(); cy.visit( ...

struggling to access $scope variable in MVC partial view using AngularJS

I am looking to include a partial in my main content. This snippet is from my _layout.cshtml page. <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.T ...

Encountering difficulty retrieving information in an Angular application on an iPad mini device

I am currently developing an angular application for a dashboard. The issue I am facing is related to making http requests from my controllers. Everything works perfectly when I build and run the project using grunt on my machine, fetching data from the ex ...

Is it possible to use both interfaces and string union types in TypeScript?

My goal is to create a method that accepts a key argument which can be either a string or an instance of the indexable type interface IValidationContextIndex. Here is the implementation: /** * Retrieves all values in the ValidationContext container. ...

Encountered Angular SSR Serve Error: NullInjectorError - StaticInjectorError in AppServerModule with the following reference:

While working on building an application with Angular's SSR and serving it, I encountered a specific error. All services and components have been properly injected. Error: ERROR Error [NullInjectorError]: StaticInjectorError(AppServerModule)[REQUEST] ...