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

AngularJS powered edit button for Laravel route parameter

I have a data list that needs to be edited using an edit button. When clicking the edit button, I need to send the ID to a Laravel controller in order to fetch the corresponding data. The initial listing was created using Angular JS. <a class="btn" hr ...

Guide to implementing fullpagejs with Angular 7 selectors

I have been working on an Angular 7 project with fullpagejs by Alvarotrigo. Everything seems to be functioning properly, but I am facing an issue where the content of my website is not visible because the color of fullpagejs covers it all. When I use norma ...

Problems arising from the layout of the PrimeNG DataView component when used alongside Prime

I've been working with a PrimeNG DataView component that requires the use of PrimeFlex's flex grid CSS classes to set up the grid structure. One of their examples includes the following instructions: When in grid mode, the ng-template element ...

Something went wrong: Unable to access the properties of an undefined variable named 'gametitle'

I am able to see the variables on the html-page, but I encountered an error specifically with the value of the gametitle ERROR TypeError: Cannot read properties of undefined (reading 'gametitle') Below is the content of the ts-file: import { ...

Attempting to utilize a namespace-style import for calling or constructing purposes will result in a runtime failure

Using TypeScript 2.7.2 and VSCode version 1.21 with @types/express, I encountered an issue where in certain cases VSCode would report errors like: A namespace-style import cannot be called or constructed, and will cause a failure at runtime. Interestingly ...

The $state.go function is malfunctioning when called from a different controller

Below is the code snippet: $stateProvider .state('home', { url: "/home", templateUrl: "views/home.tpl.html", controller:"homeController" }) .state('test', { url: '/test', templateUrl: "views/test/dashboard.tpl.html", }); Th ...

When trying to gather multiple parameters using @Param in a NestJS controller, the retrieved values turn out

Can someone help me understand why I am struggling to retrieve parameters using the @Param() decorators in my NestJS controller? These decorators are defined in both the @Controller() decorator argument and the @Get() argument. I am relatively new to Nest ...

The binding to 'videoId' cannot be established as it is not a recognized attribute of the 'youtube-player' component

Currently, I am working with Ionic 3 and Angular 5. In my application, I am integrating Youtube videos using ngx-youtube-player. However, I am encountering errors: Template parse errors: Can't bind to 'videoId' since it isn't a know ...

Is Angular Template Polymorphism Failing?

So I'm working with a base class that has another class extending it. export class Person { public name: string; public age: number; } export class Teacher extends Person { public yearsTeaching: number; } Now, in my component, I need to ...

Unable to display information stored in the Firebase database

I am struggling with a frustrating issue. My goal is to showcase the information stored in the Firebase database in a clear and organized manner, but I'm having trouble achieving this because it's being treated as an object. getData(){ firebas ...

What is the best way to designate external dependencies in WebPack that are not imported using '*'?

I need assistance with specifying office-ui-fabric-react as an external dependency in my TypeScript project using Webpack. Currently, I am importing only the modules I require in my project: import { Dialog, DialogType, DialogFooter } from 'office-u ...

Steps to integrating an interface with several anonymous functions in typescript

I'm currently working on implementing the interface outlined below in typescript interface A{ (message: string, callback: CustomCallBackFunction): void; (message: string, meta: any, callback: CustomCallBackFunction): void; (message: string, ...m ...

Can you explain the functionality of $on.constructor in AngularJS?

Recently, I attempted an XSS challenge on the PortSwigger labs website. You can find the challenge here. This is my solution to the XSS challenge: {{$on.constructor('alert(1)')()}} However, since I have no prior experience with AngularJS, I&apo ...

How can a TypeScript object be declared with a single value assignment to itself?

Whenever I try to declare an object and assign a key to itself, I encounter errors. I have attempted different methods, but the error persists. const a = { d:123, a:a//<-TS2448: Block-scoped variable 'a' used before its declaration. } co ...

What is the proper way to address the error message regarding requestAnimationFrame exceeding the permitted time limit?

My Angular application is quite complex and relies heavily on pure cesium. Upon startup, I am encountering numerous warnings such as: Violation ‘requestAnimationFrame’ handler took 742ms. Violation ‘load’ handler took 80ms. I attempted to resolve ...

I'm troubleshooting why I continue to receive a 403 status code in my HTTP request, despite having implemented CORS

While attempting to send a http request in my Angular front-end application, I am encountering an issue where the request fails with a status code 403 in a preflight request. Despite setting the necessary headers in my Node.js back-end to allow access, thi ...

Is there a method in Angular JS to monitor modifications in the DOM that doesn't involve using scope.watch?

I'm working on creating an angularjs bootstrap accordion that automatically scrolls to the top when opened. While I found some solutions that are similar to what I want: AngularJS / ui-bootstrap accordion - scroll to top of active (open) accordion ...

Enabling $sce.trustAsResourceUrl() across all platforms

Is there a way to implement something similar to this code snippet: $sce.trustAsResourceUrl('URL_HERE'); Specifically, is it possible to do this globally within the main app's config() or run() functions in order for all iFrames, img src, e ...

Is it possible for Typescript to automatically infer object keys based on the value of a previous argument?

Currently, my goal is to create a translation service that includes type checking for both tags and their corresponding placeholders. I have a TagList object that outlines the available tags along with a list of required placeholders for each translated st ...

"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 ...