1

I'm trying to get a variable to appear through both the controller prefix and the method path parameters of the decorators. I know of Nest Router, but I'd rather avoid using it while I can.

/*************************
* eneity.config.ts
*************************/
import { registerAs } from '@nestjs/config';
export default registerAs('cat', () => ({
        cat: {
            urlPrefix: 'cat',
            paramName: 'meow',
        }
    })
);
/*************************
* cat.module.ts
*************************/
import entityConfig                    from 'config/entity.config';
import { CatController }               from 'entities/cat/cat.controller';
import { ConfigModule, ConfigService } from '@nestjs/config';
@Module({
            imports    : [ConfigModule.forFeature(entityConfig),],
            providers  : [ConfigService],
            controllers: [CatController],
        })
export class CatModule {}

/*************************
* cat.controller.ts
*************************/

import { Controller, Request, Get } from '@nestjs/common';
import { ConfigService }            from '@nestjs/config';

@Controller(`${this.urlPrefix}/cat`) // <<<<< Here
export class CatController {
    private readonly urlPrefix;
    private readonly paramName;

    constructor(
        private readonly configService: ConfigService,
    ) {
        this.urlPrefix = this.configService.get<string>('cat.urlPrefix'); // animal
        this.paramName = this.configService.get<string>('cat.paramName'); // meow
    }

    @Get(`snowflake/:${this.paramName}`) // <<<<< Here
    getProfile(@Request() req) {
        return 'meowww';
    }
}

I tried to do it as is, and it keeps giving me "undefined", even though it shows up if I log it to console in the constructor. I want to be able to use the configuration to set these constants.

In the end, the route I want is: localhost/animal/cat/snowflake/meow.


Edit: I attempted it with a normal variable, and it works. Apparently the issue is with my implementation of NestJS's config package.

yaserso
  • 2,638
  • 5
  • 41
  • 73

1 Answers1

1

There's not an issue with your config service, but rather an issue with how decorators work in Typescript/JavaScript. Decorators cannot access class members, due to how the decorator context works. If you want to make the endpoint configurable, which seems like a bad idea in the first place, you can use nest-router as you mentioned.

Jay McDoniel
  • 57,339
  • 7
  • 135
  • 147
  • Heyyy! Your answer [here](https://stackoverflow.com/a/59460497/1934402) helped me earlier! Thanks for sharing your knowledge! Mind elaborating why it's a bad idea to make the endpoints "configurable"? I just want to keep a constant in every entity controller; eg. `localhost/entity/dogs` & `localhost/entity/cats` where `entity` is the constant. Also, mind pointing me to read on why decorators can't access class members on how decoractor context works? By the way, I ended up opting to use `nest-router`, because I read on an issue on GitHub that the author supported its use. – yaserso Jan 20 '20 at 17:54
  • 1
    Glad I could help. As for the "configurable" endpoint, when it comes to making a web server (like Nest helps with) usually I would avoid using environment variables when it comes to routes because if you use a system like Heroku, a malicious admin (or someone with admin access) could change your environment variables, and i doing so, change your routes and wreak havoc on your systems, setting off alerts and all sorts of problems. What I would do instead is use a `const` string and reuse that variable (which is allowed in decorators) along with the rest of the url you are expecting. – Jay McDoniel Jan 20 '20 at 22:10
  • 1
    As for the information on decorators and class-members/methods, there is some discussion in some of the issues on the Nest repo (especially the graphql one), and there is information on the Typescript website. Otherwise, it is just info I have come into – Jay McDoniel Jan 20 '20 at 22:11