Validating a single field name with various DTO types based on conditions in a NestJS application

There is a field named postData in EmailTypeDto, but it has different types based on conditions. It may be confusing to explain in words, but the code makes it clear.

export class EmailTypeDto {
  @IsEnum(EmailType)
  public type: EmailType;

  @ValidateIf((o) => o.type === EmailType.ACCOUNT_SUCCESS)
  @Type(() => AccountSuccessDto)
  @ValidateNested()
  postData: AccountSuccessDto;

  @ValidateIf((o) => o.type === EmailType.MAIN_INQUIRY)
  @Type(() => MainInquiryDto)
  @ValidateNested()
  postData: MainInquiryDto;
}

An error occurs stating that postData cannot be duplicated. Although the postData field name remains constant, its value differs based on the email type, with these variations determined within each email type DTO.

I attempted to solve this issue using @ValidatorConstraint without success. The approach was similar to this proposed solution, but did not work as expected.

@ValidatorConstraint({ name: 'EmailTypeValidation', async: true })
export class EmailTypeValidation implements ValidatorConstraintInterface {
  async validate(postData: object, args: ValidationArguments) {
    switch (JSON.parse(JSON.stringify(args.object)).type) {
      case EmailType.TEST:
        postData = AccountSuccessDto;
        return true;
      case EmailType.MAIN_INQUIRY:
        postData = MainInquiryDto;
        return true;
    }
  }
}

I experimented with different parameters for @Type and @ValidateIf, but encountered the same issue.

Answer №1

After encountering the error stating that the EmailTypeDto class cannot have 2 properties with the same name, it is necessary to make some changes.

It is recommended to utilize a union type for the postData property along with applying the @Validate decorator for your custom validation class:

import { IsEnum, IsNotEmpty, Validate} from "class-validator";

export class EmailTypeDto {
  @IsEnum(EmailType)
  public type: EmailType;

  @Validate(EmailTypeValidation)
  @IsNotEmpty()
  postData: AccountSuccessDto | MainInquiryDto;

In the custom validation class EmailTypeValidation, ensure to validate if the type belongs to the required types only:

@ValidatorConstraint({ name: 'EmailTypeValidation', async: true })
export class EmailTypeValidation implements ValidatorConstraintInterface {
  async validate(postData: object, args: ValidationArguments) {
    switch (args.object['type']) {
      case EmailType.ACCOUNT_SUCCESS:
      case EmailType.MAIN_INQUIRY:
        return true;
      default:
        return false;
    }
  }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Steps for incorporating ProxyConfig in Angular7 Application1. First, create a new

Having trouble building the application with proxy configuration. It works fine with ng serve or npm run start, but I need it to work with npm run build or ng build. After that, I want to deploy the dist folder to Tomcat webapps and make everything functio ...

Issue with displaying response data from Angular API in the template

I am retrieving categories from the backend and trying to display them in a table. However, there seems to be an issue with my code as no data is showing up in the table. Although the getFournisseurs method is successfully fetching 5 items from the backen ...

Is there a way to display the input value from an on-screen keyboard in an Angular application?

I have included my code and output snippet below. Is there a better way to display the input value when clicking on the virtual keyboard? ...

Error encountered during Jasmine unit testing for the ng-redux @select directive

Here is a snippet from my component.ts file: import { Component, OnInit } from '@angular/core'; import { select } from 'ng2-redux'; import { Observable } from 'rxjs/Observable'; import { PersonalDetailsComponent } from ' ...

Generate a Jest dummy for testing an IncomingMessage object

I am facing a challenge in writing a unit test for a function that requires an IncomingMessage as one of its parameters. I understand that it is a stream, but I am struggling to create a basic test dummy because the stream causes my tests to timeout. : T ...

What is a Generic Type in an Array?

Currently, I'm working on designing a mockup app that displays data in the form of buttons in a list. I have successfully implemented most of the features but I have encountered a problem. I have initialized an array and another class to manage the da ...

Typescript: Ways to fix the error 'rxjs/Rx does not have any exported member 'SubscriptionLike'

I'm attempting to replicate the steps outlined in this tutorial found here https://www.youtube.com/watch?v=gxCu5TEmxXE. However, upon running tsc -p, I encounter an error. Is there a specific import that I am missing? ERROR: node_modules/@angular/co ...

The 'import type' declaration cannot be parsed by the Babel parser

Whenever I attempt to utilize parser.parse("import type {Element} from 'react-devtools-shared/src/frontend/types';", {sourceType: "unambiguous"}); for parsing the statement, I come across an error stating Unexpected token, exp ...

Can you please provide an explanation on the functioning of Dependency Injection in Nestjs?

I have been delving into Nest.js and incorporating it into my project structure. Additionally, I have integrated TypeORM into the mix. The concept of Dependency Injection in Nest.js has me feeling a bit perplexed. Project Structure |-APP_MODULE |-app.co ...

Vue's computed property utilizing typed variables

I am trying to create a computed array of type Todo[], but I keep encountering this specific error: No overload matches this call. Overload 1 of 2, '(getter: ComputedGetter<Todo[]>, debugOptions?: DebuggerOptions | undefined): ComputedRef<T ...

Validator acting as a computed setter

I am facing a challenge with using a computed property to track the value in ElementUI's el-input component. The issue is that the desired value is not being displayed within the component. Specifically, I aim to limit the input length to three charac ...

Issue with <BrowserRouter>: TS2769: No suitable overload for this call available

I encountered this error and have been unable to find a solution online. As a beginner in typescript, I am struggling to resolve it. The project was originally in JavaScript and is now being migrated to TypeScript using ts-migrate. I am currently fixing er ...

Tips for displaying bar chart labels effectively with ChartJS

I am working on an Angular project and I would like to incorporate a barchart using ChartJS. The data for this chart can vary in size, sometimes being very large. One issue I have encountered is that when the number of data points is large, the labels ove ...

What is the best way to retrieve app.state in a Remix project when running a Cypress test?

One way Cypress can expose an app's state to the test runner is by using the following approach in React: class MyComponent extends React.Component { constructor (props) { super(props) // only expose the app during E2E tests if (window.C ...

Debugging with Typescript in Visual Studio Code

I attempted to use the solution found here: how to debug typescript files in visual studio code However, when I set a breakpoint in my .ts files, the debugger indicates that the file is not found. Oddly enough, breakpoints in the .js files are working fin ...

What is the reason behind document.body not being recognized as an HTMLBodyElement?

Why does Visual Studio suggest that document.body is an HTMLElement instead of an HTMLBodyElement? I've searched for an answer without success. class Test { documentBody1: HTMLBodyElement; documentBody2: HTMLElement; cons ...

Compile time error due to TypeScript enumeration equality issue

Currently, I am developing a system to manage user roles within my website using TypeScript enumeration. This will allow me to restrict access to certain parts of the site based on the user's role. The primary challenge I am facing is comparing the u ...

Arrange a JavaScript map based on its values and ensure that a specific field index remains at the top position

I'm sure this question may seem simple to some, but as a JavaScript novice, I couldn't find the answer myself. Here is the code snippet I'm working with: Let map = new Map<String,String> map.set('0', select) map.set('1&a ...

Attaching a function to a designated slot attribute

Currently, I am utilizing VUE 2.6.11 along with class components. My current objective involves encapsulating components that can serve as modals inside a separate component responsible for managing the modal state. According to the documentation, it is p ...

In TypeScript, both 'module' and 'define' are nowhere to be found

When I transpile my TypeScript using "-m umd" for a project that includes server, client, and shared code, I encounter an issue where the client-side code does not work in the browser. Strangely, no errors are displayed in the browser console, and breakpoi ...