I am using the following interceptor to transform the gameLevel from string to number.
@Injectable()
export class EnumStringToNumberInterceptor implements NestInterceptor {
constructor() {}
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next.handle().pipe(map(data => {
if (data && data.list) {
data.list.forEach(d => {
d['gameLevel'] = Number(d['gameLevel']);
})
} else if (data && data.gameLevel) {
data['gameLevel'] = Number(data['gameLevel']);
}
return data;
}));
}
}
I want to pass gameLevel as key somehow in constructor something like the following –
constructor(private readonly key: string) {}
// and do something like this
d[key] = Number(d[key]);
By achieving this I will be making this interceptor more general to use it in different such use cases when key will be differing.
>Solution :
If you have nothing being injected into the interceptor, then a simple new Interceptor('key or whatever string') works well.
If you do have something being injected, I would suggest making use of reflection and following Nest’s docs on setting up custom metadata that the interceptor can read at runtime.
Something along the lines of
export const GameLevel = (key: string) => SetMetadata('GAME_LEVEL_METADATA', key);
Then in your controller you can use @GameLevel('someLevelKey') and in the interceptor you can do something along the lines of
@Injectable()
export class EnumStringToNumberInterceptor implements NestInterceptor {
constructor(private readonly reflector: Reflector) {}
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const level = this.reflector.getAllAndOverride('GAME_LEVEL_METADAT', [context.getClass(), context.getHandler()]);
return next.handle().pipe(map(data => {
if (data && data.list) {
data.list.forEach(d => {
d[level] = Number(d[level]);
})
} else if (data && data[level]) {
data[level] = Number(data[level]);
}
return data;
}));
}
}