#Supplying an object as a decorator parameter

13 messages · Page 1 of 1 (latest)

low flower
#

Hi,
I'm trying to write a decorator that will be used on a parameter in a controller route function. I'm trying to supply it with an object, but the parameter that comes back in the decorator function is coming in as undefined. a string type does not have the same issue, so I'm wondering if that's a limitation of decorators. Here's what I'm trying:

export const ParsedBodyDecorator = createParamDecorator<ZodObject<ZodRawShape>>(
  (schema, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest<Request>();

    const result = schema.safeParse(request.body); // ERROR: schema is undefined
    if (!result.success) {
      throw new BadRequestException(result.error);
    }

    return result.data;
  },
);

And I'm using it in a route function like:

@ParsedBodyDecorator(mySchema) data: value
upper slate
#

From what I can see this should be fine

low flower
#

Hm, well I'm stumped then. Guess I'll do some more digging.
And the return value of that tag handler function is what gets set as the parameter value in the function using it, right?

upper slate
#

Yep, that then goes on to any pipes if you have them

low flower
#

Cool. I'm probably doing something wrong then, just wanted to make sure I wasn't making an assumption somewhere.

#

oh, you know what, I wonder if it's treating my Zod schema as a pipe

#

It works with pretty much any other object type, however the second I supply it a Zod schema it stops passing to the handler, and does some weird stuff with the returned value;

upper slate
#

Oh, it might be. You'd need to do it like export const ParsedBodyDecorator = (schema) => createParamDecorator() I think. Might need another () at the end

low flower
#

Yep, that makes sense. Builder for the builder.

#

It's ugly, but this works:

@ParsedBody(mySchema)() data: MyData

I'll find out in a second, but I wonder if it's possible for a decorator to help Typescript infer the parameter type without having to explicitly declare it.

upper slate
#

Oh, I was thinking do export const ParsedBodyDecorator = (schema) => createParamDecorator()() so it's still just @ParsedBodyDecorator(mySchema)

low flower
#

Oh duh

#

that makes more sense