hikvineh
hikvineh

Reputation: 150

NestJs - Calling a method from a service inside a Custom Decorator

Based on this answer, I tried to implement a function from another service inside a decorator.

Here is my attempt:

export function ClearCache() {
  const injectCacheService = Inject(CacheService);

  return (target: any, _: string, propertyDescriptor: PropertyDescriptor) => {
    injectCacheService(target, 'service'); // this is the same as using constructor(private readonly logger: LoggerService) in a class

    //get original method
    const originalMethod = propertyDescriptor.value;

    //redefine descriptor value within own function block
    propertyDescriptor.value = async function (...args: any[]) {
      try {
        console.log(this);
        const service: CacheService = this.service;
        service.clearCacheById(args[1]);

        return await originalMethod.apply(this, args);
      } catch (error) {
        console.error(error);
      }
    };
  };
}

But I got Property 'service' does not exist on type 'PropertyDescriptor'.ts(2339)

Any idea on what part I am missing?

Update:

tsconfig.json has "strict":true. If it is enabled, then "this" would be strictly use the PropertyDescriptor interface.

Fixed the issue by changing "strict": false in the tsconfig.json.

How to reproduce?

Upvotes: 2

Views: 9638

Answers (2)

Flo
Flo

Reputation: 3127

You can fix it easier with the follow: const service: CacheService = (this as any).service;

Greetings, Florian

Upvotes: 0

The Geek
The Geek

Reputation: 1283

Its unclear if you are using the NestJS cache-manager wrapper, if so you need to use the provider token when injecting and the type would be Cache.

export function ClearCache() {
    
    const injector = Inject(CACHE_MANAGER)

    return (target: any, _key?: string | symbol, descriptor?: TypedPropertyDescriptor<any>) => {
        
        injector(target, 'cacheManager')

        const originalMethod = descriptor.value

        descriptor.value = async function (...args: any[]) {
            try {
                const service: Cache = this.cacheManager
                service.delete(args[1])
                return await originalMethod.apply(this, args)
            } catch (err) {
                console.error(err)
                return originalMethod(args)
            }
        }
    }
}

If it is a different service, ensure that you are using the correct provider token, it is in the current modules scope and instantiated. If it isn't in current module, check it is global

Uploaded minimal repo of above code here.

Update:

tsconfig.json has "strict":true. If it is enabled, then "this" would be strictly use the PropertyDescriptor interface.

Fixed the issue by changing "strict": false in the tsconfig.json.

Upvotes: 5

Related Questions