nestjsx/crud

id's are returned as array of two instead of one numeric value

qstyler opened this issue · 5 comments

Bug Report

I have a basic setup with one single entity and I create a CRUD service/controller by just following the docs.

But every entity returned has its ID transformed to an array of two IDs:

{
    "id": [
        2,
        2
    ],
    "code": "OkWtWjq-",
    "name": "test",
    "userPnl": "xxxxxx",
    "data": {
        "test": "12341234",
        "test2": "987654"
    },
    "createdAt": "2022-11-02T07:16:45.803Z"
}

The same happens when I request a list of IDs and get a newly created entity in return for POST and PATCH.

And I see that SQL generated looks like this. For some reason, it lists "Analysis"."id" two times.

SELECT "Analysis"."id" AS "Analysis_id", "Analysis"."id" AS "Analysis_id", "Analysis"."code" AS "Analysis_code", "Analysis"."name" AS "Analysis_name", "Analysis"."userPnl" AS "Analysis_userPnl", "Analysis"."data" AS "Analysis_data", "Analysis"."createdAt" AS "Analysis_createdAt" FROM "ComGen2"."analysis" "Analysis" WHERE ("Analysis"."userPnl" = @0) -- PARAMETERS: ["xxxxxx"]

Here's the entity:

import {
  BeforeInsert,
  Column,
  CreateDateColumn,
  Entity,
  PrimaryGeneratedColumn,
  Unique,
} from 'typeorm';
import { nanoid } from 'nanoid';
import { ApiProperty } from '@nestjs/swagger';

@Entity({
  name: 'analysis',
})
@Unique('unique_code', ['code'])
@Unique('unique_user_and_name', ['userPnl', 'name'])
export class Analysis {
  @ApiProperty()
  @PrimaryGeneratedColumn()
  id: number;

  @ApiProperty()
  @Column({
    name: 'code',
  })
  code: string;

  @ApiProperty()
  @Column()
  name: string;

  @ApiProperty()
  @Column()
  userPnl: string;

  @ApiProperty()
  @Column({
    type: 'simple-json',
  })
  data: JSON;

  @ApiProperty()
  @CreateDateColumn()
  createdAt: Date;

  @BeforeInsert()
  setCode() {
    if (!this.code) {
      this.code = nanoid(8);
    }
  }
}

Controller:

import { Controller, UseGuards } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { Crud, CrudAuth, CrudController } from '@nestjsx/crud';

import { AzureADBearerGuard } from '../../auth';

import { AnalysisService } from './analysis.service';
import {
  Analysis,
  CreateAnalysisDto,
  UpdateAnalysisDto,
  User,
} from '../../domain';

@Controller()
@UseGuards(AzureADBearerGuard)
@ApiTags('analysis')
@Crud({
  model: {
    type: Analysis,
  },
  dto: {
    create: CreateAnalysisDto,
    update: UpdateAnalysisDto,
  },
})
@CrudAuth({
  property: 'user',
  filter: (user: User) => ({
    userPnl: user.userPnl,
  }),
  persist: (user: User) => ({
    userPnl: user.userPnl,
  }),
})
export class AnalysisController implements CrudController<Analysis> {
  constructor(readonly service: AnalysisService) {}
}

And service:

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { TypeOrmCrudService } from '@nestjsx/crud-typeorm';

import { Analysis } from '../../domain';

@Injectable()
export class AnalysisService extends TypeOrmCrudService<Analysis> {
  constructor(@InjectRepository(Analysis) repo: Repository<Analysis>) {
    super(repo);
  }
}

These are the versions I'm using:

"@nestjs/core": "^9.1.6",
"@nestjs/typeorm": "^9.0.1",
"@nestjsx/crud": "^5.0.0-alpha.3",
"@nestjsx/crud-typeorm": "^5.0.0-alpha.3",
"mssql": "^7.3.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.13.2",

I tried to use version ^4 but with the same result.

The schema generated by Swagger seems correct though.
image

I'm getting a normal result if I call findBy on a repo.

const analysisList = await this.repo.findBy({
  userPnl: 'xxxxxx',
});
console.log(analysisList);

Generated SQL is ok:

SELECT "Analysis"."id" AS "Analysis_id", "Analysis"."code" AS "Analysis_code", "Analysis"."name" AS "Analysis_name", "Analysis"."userPnl" AS "Analysis_userPnl", "Analysis"."data" AS "Analysis_data", "Analysis"."createdAt" AS "Analysis_createdAt" FROM "ComGen2"."analysis" "Analysis" WHERE ("Analysis"."userPnl" = @0) -- PARAMETERS: ["xxxxxx"]

And here's the console output:

[
  Analysis {
    id: 2,
    code: 'OkWtWjq-',
    name: 'test',
    userPnl: 'xxxxxx',
    data: { test: '12341234', test2: '987654' },
    createdAt: 2022-11-02T07:16:45.803Z
  }
]

Somehow this has something to do with “typeorm” version. If I change it to "typeorm": "^0.2.0" things start to work normally.

This is actually fixed in this PR #797

Hey @qstyler, I got the same problem.. can u share how your package json (nestjsx versions, mssql, typeorm) turned out?

@lhfioravanso It looks like the maintainer doesn't really maintain this project, so I used a fork. There are several out there.
Although several days ago he approved several PRs, that solved this problem among others.
Unfortunately, it hasn't been released to npm yet.