TypeScript class decorator for extending methods

I have been extensively researching decorators in TypeScript, but I have not been able to find comprehensive documentation that suits my specific needs.

After exploring two possible solutions - AOP and Decorator, it seems like AOP is not fully functional yet.

My situation involves implementing a security library where I need to invoke methods "enterAction" and "leaveAction" whenever the current page changes.

Given that I have Angular/Ionic lifecycle events for page changes (load/leave), I prefer to centralize the overrides in one place rather than modifying each individual page component. This way, when adding a new page, I won't forget to implement it.

Hence, my plan was to add a decorator on each page class which would incorporate calls to my secure library's actions based on the load/leave events being triggered.

Currently, I am able to create a class decorator. However, I am unsure of how to properly override method calls.

This is how I have defined my class decorator:

@security
@Component({
    selector: 'my-app',
    template: '<h1>Hello Angular!</h1>'
})
export class AppComponent implements OnInit {
    private toto= "demo";
    constructor() {
        console.log("construct!");
    }
    ngOnInit() {
        console.log('onInit');
        this.method1();
    }
    method1() {
        console.log('method 1 : '+ this.toto);
    }
}


function security<TFunction extends Function>(target: TFunction): TFunction     {
    var method1 = target.prototype.method1;
    Object.defineProperty(target.prototype, 'method1', {
        value: function() {
            console.log('enterAction here');
            // How to call real method1() here ?
            // Call of method1() will fail since it don't know AppCompnent.toto here
            return '';
        }
    });
    return target;
}

Regards,

EDIT

Eventually, I discovered an alternative approach that doesn't involve using decorators to solve my issue.

Answer №1

You are on the right track, just remember to utilize the apply method:

function enhanceSecurity<T extends Function>(target: T): T     {
    var originalMethod = target.prototype.originalMethod;
    Object.defineProperty(target.prototype, 'originalMethod', {
        value: function() {
            console.log('enterAction here');
            return originalMethod.apply(this, arguments);
        }
    });
    return target;
}

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

Exploring the potential of utilizing dynamic types in a TypeScript React application alongside React Hook Form

Currently, I am in the process of converting a React application that was previously not using TypeScript to now incorporate TypeScript. I am facing an issue with the use of React Hook Form's setValue method. The component I am working on serves as a ...

Node.js and Angular.js communication: from requests to responses

Efforts are being made to solicit data from a node.js server through angular.js. However, an unexpected challenge persists: post-data response, a stark white browser screen shows up with the JSON object in plain sight. The goal is for angular.js to acknowl ...

Tips for customizing the legend color in Angular-chart.js

In the angular-chart.js documentation, there is a pie/polar chart example with a colored legend in the very last section. While this seems like the solution I need, I encountered an issue: My frontend code mirrors the code from the documentation: <can ...

Determine the data type of the property in an object that needs to be provided as an argument to a

I am currently in the process of creating a function that can take in an object with a specific data type, as well as a function that acts on that data type as its argument. const analyze = < Info extends object, F extends {initialize: Info; display ...

What is the method for designating a precise subtype within an interface?

I am facing an issue with my Carousel. It is supposed to render a card with data if available, or a skeleton when there is no data. The error I am encountering is: Type 'EmptyElement' is not assignable to type 'Annonce | Annonce2'. Ty ...

A Promise is automatically returned by async functions

async saveUserToDatabase(userData: IUser): Promise<User | null> { const { username, role, password, email } = userData; const newUser = new User(); newUser.username = username; newUser.role = role; newUser.pass ...

The specified property is not present in the type '{}'

I've been incorporating Typescript into my React application Within my mapStateToProps, this is the code I'm using const mapStateToProps = (state: AppState) => { console.log(state) return { ...state.player, position: ...

Conquer TypeScript type errors by utilizing Ramda's groupBy function

I've been facing a challenge with fixing this typescript error related to using ramda's groupBy function: 245: const groups = R.groupBy((row: Record) => { 246: return row[this.props.groupBy] 247: })(this.props.data) The def ...

Is it possible to dynamically generate variables for React hooks during runtime?

Are there any methods to dynamically create variables for react hooks, allowing the values of these variables to be extracted and sent to an API at runtime instead of having predefined variable names set during design time like I am currently doing? Take ...

Contrast the differences between arrays and inserting data into specific index positions

In this scenario, I have two arrays structured as follows: arr1=[{room_no:1,bed_no:'1A'}, {room_no:1,bed_no:'1B'}, {room_no:2,bed_no:'2A'}, {room_no:3,bed_no:'3A'}, {room_no:3,bed_no:'3B ...

"Utilizing Ionic version 2 to initiate a function from the calling page within a provider

I am facing an issue where I need to call a function (f1) from a provider and then from that function (f1), call another function on the page. Here is the code for page1.ts: import { Component } from '@angular/core'; import { NavController } ...

Problem: Unable to locate the TypeScript declaration file

I am facing an issue with my TypeScript configuration. I have two files in /src/models/: User.ts and User.d.ts. In User.ts, I am building a class and trying to use an interface declaration for an object defined in User.d.ts. However, User.ts is unable to a ...

Received a collection of null values within the Semantic UI search dropdown

In my rails + angular application, I am utilizing semantic ui. There is a search dropdown that displays undefined values when typing the letter s, but works fine for other single letters. Strangely, no server request is made when typing the letter s, and I ...

Determine the datatype of an object within another object, even when the datatype of the object might not be

Here is the structure I am working with: type MyType = { a?: { b: number; } } I am trying to access the type of b. After that, my goal is to create a new type based on this: type AnotherType = { mytype: MyType['a']['b'] } ...

Learn how to utilize the "is" status in Postma within your code, even when this particular status is not included in the response

Service.ts Upon invoking this function, I receive a JSON response similar to the following: public signupuser(user: Users): Observable<boolean> { let headers = new Headers(); headers.append('Content-Type', 'application/json&a ...

Angular HTTP Patch method requires explicitly defined HTTP options as input parameters

I encountered a challenge with using Angular's HTTP patch method and noticed that the overloaded function patch(url, body, options) only accepts hardcoded values for HTTP options. An example of a hardcoded approach that works: patchEntity(id: number) ...

Tips for eliminating the undefined/null values from an array nested within another array in Angular

DATA = [{ application: [{ name: 'Room1' },{ name: 'Room2' },{ name: 'Room3' },{ name: 'Room4' },{ name: 'Room5' }], name: 'Batch 1&ap ...

Restricted to using solely the letters a through z within an angular framework

I need a way to limit user input to just English characters and exclude numbers or any other languages. I've attempted to achieve this using the following directive, but it's not working as expected. Check out my demo on JSFiddle. app.directive( ...

Leveraging AngularJS $promise in conjunction with NgResource

As I delve into the world of AngularJS, I have encountered promises which have proven to be quite beneficial in my learning journey so far. Now, I am eager to explore the optional library resource.js in AngularJS. However, I stumbled upon examples that lef ...

Angular UI Typeahead failing to display placeholder text

My input field is using typeahead, but the placeholder text is not showing up. How can I fix this issue and make the placeholder appear? The version of "angular-bootstrap" that I am currently using is "~0.14.0" <input type="text" name="scheduler_name" ...