tsed: @BodyParams doesn't work well with string

Information

  • Version: 5.x
  • Type: Issue

Description

@BodyParams doesn’t work well with string

Example

I use postman to send request to server, my json request:

{
    "name": "213"
}

My controller:

@Controller("/templates")
@Docs("api-v1")
export class TemplateController {
  private connection: Connection;
  constructor(
    private templateService: TemplateService
  ) {}
  // $afterRoutesInit() {
  //   this.connection = getConnection("default");
  // }
  @Post("/")
  @ContentType("application/json")
  async create(
    @HeaderParams("clientId") clientId: number,
    @BodyParams() templateRequest: TemplateRequestModel,
    @Req() req: Express.Request,
    @Res() res: Express.Response
  ) {
    console.log(templateRequest.name); // return { [String: ''] '0': '2', '1': '1', '2': '3' }. // Wrong value
    console.log(req.body.name); // return 213
}

My TemplateRequestModel :

export class TemplateRequestModel {
  name: string;
}

My Server.ts

import {
  ServerLoader,
  ServerSettings,
  GlobalAcceptMimesMiddleware
} from "@tsed/common";
import "reflect-metadata";
import dotenv from "dotenv";
const cookieParser = require("cookie-parser");
const bodyParser = require("body-parser");
const compress = require("compression");
const methodOverride = require("method-override");

import "@tsed/typeorm";
import "@tsed/swagger";

import "./middlewares/ErrorHandlerMiddleware"
import config from "./config";
const rootDir = __dirname;

@ServerSettings({
  rootDir,
  acceptMimes: ["application/json"],
  httpPort: config.httpPort,
  httpsPort: false,
  // // config typeorm
  typeorm: [
    {
      name: "default",
      host: "xxxx",
      type: "mysql",
      port: 3306,
      username: "xxxx",
      password: "xxxx",
      database: "xxxx",
      logging: true, // logging query for debugging
    }
  ],
  // config swagger
  swagger: [
    {
      path: "/api-docs/v1",
      doc: "api-v1",
      showExplorer: true // display search bar
    }
  ],
  // mount controller + routing
  mount: {
    "/api/v1": `${rootDir}/controllers/v1/*.ts`
  }
})
export class Server extends ServerLoader {
  public $onMountingMiddlewares(): void | Promise<any> {
    dotenv.config();
    this.use(GlobalAcceptMimesMiddleware)
      .use(cookieParser())
      .use(compress({}))
      .use(methodOverride())
      .use(bodyParser.json({ limit: "50mb" }))
      .use(
        bodyParser.urlencoded({
          extended: true,
          limit: "50mb"
        })
      );
    return null;
  }
}

I read documentation

@BodyParams decorator provide quick access to an attribute Express.request.body.

But it seems like @BodyParams and Express.request.body are returning different values. But when I test with the object, both of them return the same value. Any advice is welcome!

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 16

Most upvoted comments

Can you checkout again the example: https://github.com/Romakita/tsed-tranbavinhson And tell if it works. I tried with different scenario and for me it works. Here the curl:

curl -X POST "http://0.0.0.0:8080/rest/templates" -H  "accept: application/json" -H  "Content-Type: application/json" -d "{  \"name\": \"test\"}"

The problem come from the body-parser middleware. But not sure why you have a bad deserialization.

So test the latest example and tell me. See you