befabry
befabry

Reputation: 812

Property-based injection with an Abstract Class

I am trying to add an Abstract method to serialize my response objects in order to hash the id's. That would require to have a property-based injection in order to not pass lots of variables through the constructor.

The class that will be used to Serialize :

import { AbstractHash } from 'src/global/abstract.hash';
import { IItems } from '../items.interface';
import { Injectable } from '@nestjs/common';

@Injectable()
export class ResponseItem extends AbstractHash implements IItems {
  name: string;
  price: number;
  type: string;

  constructor(partial: Partial<IItems>) {
    super();
    Object.assign(this, partial);
  }
}

The abstract class :

import { HashIdHelper } from 'src/hash-id.helper';
import { Exclude, Expose } from 'class-transformer';
import { Inject, Injectable } from '@nestjs/common';

@Injectable()
export abstract class AbstractHash {
  @Exclude()
  id: number;

  //@Inject('HASHID_HELPER') // Neither works
  @Inject(HashIdHelper)
  public readonly hashIdHelper: HashIdHelper;

  @Expose({ name: 'id' })
  encodedId() {
    console.log(this.hashIdHelper); // -> undefined
    console.log(HashIdHelper);
    return this.hashIdHelper.encode(this.id);
  }
}

The controller :

// imports

@UseInterceptors(ClassSerializerInterceptor)
@Controller('items')
export class ItemsController {
  constructor(
    private readonly itemsService: ItemsService,
    @Inject('HASHID_HELPER') private readonly hash: HashIdHelper, // <-- Ok
  ) {}


  @Get(':id')
  async findOne(@Param('id') id: string) {
    console.log(this.hash.encode(+id)); // <-- Ok
    const item = await this.itemsService.findOne(parseInt(id));

    console.log(new ResponseItem(item));
    return new ResponseItem(item); // <-- undefined attribute, see above
  }

}

The repository : https://github.com/befabry/caddie/tree/hash_id

Thanks for the help

Upvotes: 0

Views: 2236

Answers (1)

Jay McDoniel
Jay McDoniel

Reputation: 70402

You're calling new ClassInstance() so you are 100% in control of the class and it's properties. Nest will not inject anything on a manually instantiated class, because it's not managed by Nest's lifecycle in the first place. You can use moduleRef.create to have Nest create an instance for you, but once you use the keyword new you are in charge of that instance.

Upvotes: 1

Related Questions