'This' loses its value within a function once the decorator is applied

Scenario: Exploring the creation of a decorator to implement an interceptor for formatting output.

Issue at Hand: Encountering 'this' becoming undefined post application of the decorator.

// custom decorator
function UseAfter(this: any,  fn: (...args: any) => any){
    return (target: any, key: string, descriptor: PropertyDescriptor) => {
        const originalMethod = descriptor.value

        descriptor.value = (...innerArgs:any) => {
            let result = originalMethod.apply(this, innerArgs)

            return fn(result)
        }
    }
}

const formatData = (arg1: any) => {
    return {
        data: JSON.stringify(arg1)
    }
}

class Example {

    additionalMethod() {
        console.log('performing instance method')    
    }

    @UseAfter(formatData)
    function1() {
        console.log(this) // < --- now undefined
        this.additionalMethod()
        return 'success'
    }
}

const exampleInstance = new Example()
exampleInstance.function1()

Answer №1

To ensure a comprehensive approach,

Avoid using arrow functions with descriptors to maintain the correct context of this.

// custom decorator
function UseAfter(this: any,  fn: (...args: any) => any){
    return (target: any, key: string, descriptor: PropertyDescriptor) => {
        const originalMethod = descriptor.value

        // use regular function instead of arrow function
        descriptor.value = function (...innerArgs:any) { 
            let result = originalMethod.apply(this, innerArgs)

            return fn(result)
        }
    }
}

const middleware = (arg1: any) => {
    return {
        data: JSON.stringify(arg1)
    }
}

class Test {
    otherInstanceMethod() {
        console.log('accessing instance method')    
    }

    @UseAfter(middleware)
    method1() {
        console.log(this)
        this.otherInstanceMethod()
        return 'ok'
    }
}

const test = new Test()
test.method1()


The expected output should be -

Test {}
accessing instance method

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

What is the reason for calling Proxy on nested elements?

Trying to organize Cypress methods into a helper object using getters. The idea is to use it like this: todoApp.todoPage.todoApp.main.rows.row .first().should('have.text', 'Pay electric bill'); todoApp.todoPage.todoApp.main.rows.ro ...

Is it necessary to use Generics in order for a TypeScript `extends` conditional type statement to function properly?

Looking to improve my understanding of the extends keyword in TypeScript and its various uses. I recently discovered two built-in utilities, Extract and Exclude, which utilize both extends and Conditional Typing. /** * Exclude from T those types that are ...

There is no universal best common type that can cover all return expressions

While implementing Collection2 in my angular2-meteor project, I noticed that the code snippets from the demo on GitHub always result in a warning message being displayed in the terminal: "No best common type exists among return expressions." Is there a ...

How to arrange data in angular/typescript in either ascending or descending order based on object key

Hey there! I'm fairly new to Angular and have been working on developing a COVID-19 app using Angular. This app consists of two main components - the State component and the District component. The State component displays a table listing all states, ...

TypeScript encounters difficulty in locating the namespace within a Node.js dependency

I am faced with a situation where I have two node.js packages that each contain type declaration files. In package a, there is a namespace declared that I want to reference in package b. Package A index.d.ts declare namespace foo { export interface A ...

How to specify the return type of a promise from an observer in Angular 6

Typically, I prefer using observables. However, in order to avoid 'callback hell' in this particular scenario, I decided to use toPromise(). Unfortunately, I encountered a lint error message when trying to define the return type: The 'Obj ...

The absence of the import no longer causes the build to fail

Recently, after an update to the yup dependency in my create react-app project, I noticed that it stopped launching errors for invalid imports. Previously, I would receive the error "module filename has no exported member X" when running react-scripts buil ...

Creating a welcome screen that is displayed only the first time the app is opened

Within my application, I envisioned a startup/welcome page that users would encounter when the app is launched. They could then proceed by clicking a button to navigate to the login screen and continue using the app. Subsequently, each time the user revisi ...

The issue with the tutorial is regarding the addHero function and determining the source of the new id

Whenever I need to introduce a new superhero character, I will utilize the add(string) function found in heroes/heroes.component.ts add(name: string): void { name = name.trim(); if (!name) { return; } this.heroService.addHero({ name } as H ...

TS2322 error: Attempting to assign type 'any' to type 'never' is invalid

Currently, I am utilizing "typescript"- "3.8.3", and "mongoose": "5.9.11". Previously, my code was functional with version "typescript": "3.4.x", and "mongoose": "4.x". Here is a snippet of my code: https://i.stack.imgur.com/j3Ko2.png The definition for ...

Why is Mongoose returning null when using findOne?

Here is a sample request: interface IGetFullnameRequest extends IAuthenticatedRequest { readonly body: Readonly<{ fullname: string; }>; } This is the controller function to get the fullname: const getFullname = async (req: IGetFullna ...

Invoke the method in customButton component of fullcalendar

I've integrated a custom button into my fullcalendar: ngOnInit() { this.calendarOptions = { customButtons: { custom1: { text: 'Add event', click() { this.openModal(); } } }, height: 600, editable: t ...

Issue with Discord.js (14.1) - Message Handling Unresponsive

After developing a sizable Discord Bot in Python, I decided to expand my skills and start learning JS. Despite thoroughly studying the documentation and comparing with my original Python Bot regarding intents, I am facing difficulties getting the message ...

Retrieve a specific element from an array list

Hey everyone, I'm facing a problem in my application where I need to extract a specific value from my array and display it in a table for users to see. Check out the code snippet below: Here's my mock data: { "Data": "2020-0 ...

Angular 7 ERROR: The SystemJS reference is missing

In the process of developing an Angular 7 project with systemjs for dynamic module loading, I encountered an issue. Upon attempting to utilize it, I encountered the following error: ERROR ReferenceError: SystemJS is not defined Within my package.json f ...

Utilizing the 'create' function in sqlite each time I need to run a query

I've been diving into SQLite within the Ionic framework and have pieced together some code based on examples I've encountered. import { Component } from '@angular/core'; import { IonicPage, NavController, NavParams } from 'ionic-a ...

Is there a way to operate both websocket and http methods concurrently on a server in Typescript?

I have a question regarding running a websocket server with the route "ws://localhost:port" using the 'ws' library. It requires the app instance of 'express' and also features http routes such as "http://localhost:port/auth/login". I am ...

Establishing a pair of separate static directories within Nest

I am looking to utilize Nest in order to host two static applications. Essentially, I have a folder structure like this: /public /admin /main Within my Nest application, I currently have the following setup: app.useStaticAssets(join(__dirn ...

It seems that every time you save data in Angular, the local storage array gets overwritten

While using Angular, I encountered an issue with saving to local storage. The code works fine for saving items initially, but on refreshing the page and trying to add more objects to the local storage array, it overwrites instead of appending. Can you help ...

A special term in Typescript that consistently points to the present object within the class

Is it feasible to utilize a reference to the current instance of a class in Typescript, similar to "this" in C# and Java, rather than the typical binding context interpretation in JavaScript? ...