Circular Dependency with Nestjs Swagger 4

Viewed 10210

When I updated the @nest/swagger library to version 4, this error happened:

(node:16134) UnhandledPromiseRejectionWarning: Error: A circular dependency has been detected (property key: "customer"). Please, make sure that each side of a bidirectional relationships are using lazy resolvers ("type: () => ClassType").
    at SchemaObjectFactory.createNotBuiltInTypeReference (/opt/desenvolvimento/Haizen/projectx_back/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js:182:19)
    at SchemaObjectFactory.mergePropertyWithMetadata (/opt/desenvolvimento/Haizen/projectx_back/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js:117:25)
    at /opt/desenvolvimento/Haizen/projectx_back/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js:66:35
    at Array.map (<anonymous>)
    at SchemaObjectFactory.exploreModelSchema (/opt/desenvolvimento/Haizen/projectx_back/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js:65:52)
    at SchemaObjectFactory.createNotBuiltInTypeReference (/opt/desenvolvimento/Haizen/projectx_back/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js:187:37)
    at SchemaObjectFactory.mergePropertyWithMetadata (/opt/desenvolvimento/Haizen/projectx_back/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js:117:25)
    at /opt/desenvolvimento/Haizen/projectx_back/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js:66:35
    at Array.map (<anonymous>)
    at SchemaObjectFactory.exploreModelSchema (/opt/desenvolvimento/Haizen/projectx_back/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js:65:52)

My model class seems to this:

@Entity()
export class Job {
.
.
.
    @ManyToOne(type => Customer, customer => customer.jobs)
    @ApiProperty({ type: Customer })
    customer: Customer;
}
6 Answers

The solution that worked for me was to declare in @ApiProperty() the type with arrow function, like below:

@Entity()
export class Job {
.
.
.
    @ManyToOne(type => Customer, customer => customer.jobs)
    @ApiProperty({ type: () => Customer })
    customer: Customer;
}

There are at least three more cases where you get the same error message, even though they have nothing to do with bidirectional relationships:

Enum as type

Wrong:

@ApiProperty({
    type: Salutation
})
public salutation: Salutation;

Correct:

@ApiProperty({
    enum: Salutation
})
public salutation: Salutation;

Anonymous types

Wrong:

@ApiProperty({
})
public address: {
    street: string;
    houseNumber: string;
};

Correct:

@ApiProperty({
    type: Address
})
public address: Address;

null

Wrong:

@ApiProperty({
    description: 'This always returns null for downward compatibility'
})
public someLegacyField: null;

Correct:

@ApiProperty({
    description: 'This always returns null for downward compatibility',
    type: String; // needed to avoid error
})
public someLegacyField: null;

I created an issue on Github for this: https://github.com/nestjs/swagger/issues/1475

For anyone who had this problem as well, you can change the type key to the enum key on the @ApiProperty. This worked for me.

I've also encountered this issue recently. In my case, I've used a few validators in the same file in my custom-validations folder. The error "A circular dependency has been detected" only appears after nest build and node dist/main.

I'm not sure if this is an issue of NestJs + Swagger after generating a build or not. Apparently, my fix was to put the validators into several files (each file contains 1 validator), it works for me.

enter image description here

I encountered this issue when I used type interfaces on nested properties of an entity

Incorrect:

export class BookLikes {
  bookLikes: {
    user: User;
    book: Book;
  }[];
}

Nest.js recommends using classes instead - even on nested properties:

Correct:

export class BookLikes {
  bookLikes: BookLike[];
}

export class BookLike {
  user: User;
  book: Book;
}

Take a look at this bugfix

I managed to make my enum (ProcessCat) working like this:

  @ApiProperty({
    enum: ProcessCat,
    enumName: 'ProcessCat',
    isArray: true,
  })
  category: ProcessCat;

And thus the NestJS compiles properly.

Related