What is the method for comparing fields within an input type in type graphql with the assistance of class validator decorators?

I am working with the following example input type:

@InputType() 

class ExampleInputType {

@Field(() => Number)
@IsInt()
fromAge: number

@Field(() => Number)
@IsInt()
toAge: number

}

Can I validate and compare the toAge and fromAge fields in this scenario using decorators from a validator library like class-validator?

Answer №1

If you're looking to ensure password integrity through a tailored validator, consider exploring the option of a custom validation function. Here's a useful resource discussing how to compare passwords and password confirmations within your application: Password confirmation in TypeScript with `class-validator`

Answer №2

It may be a bit delayed, but I have come up with a solution using a customized validator to achieve the desired outcome.

import {
  ValidationOptions,
  registerDecorator,
  ValidationArguments
} from 'class-validator';

class GenericModel {}

/**
 * Introducing a customizable custom validation method
 */
export const createCustomValidator = <Model extends GenericModel>(
  validatorName: string,
  validatorFunc: (a: unknown, b: unknown) => boolean,
  modelTypeGuard: (obj: unknown) => obj is Model
) => {
  return (
    otherPropertyName: keyof Model,
    validationOptions?: ValidationOptions
  ) => {
    return (obj: Model, propertyName: string) => {
      registerDecorator({
        name: validatorName,
        target: obj.constructor,
        propertyName,
        constraints: [otherPropertyName],
        options: validationOptions,
        validator: {
          validate(value: string, args: ValidationArguments) {
            const model = args.object;
            if (!modelTypeGuard(model)) {
              return false;
            }

            return validatorFunc(value, model[otherPropertyName]);
          }
        }
      });
    };
  };
};

An illustration of how this can be applied:

const isLessThanOrEqualTo = (a: unknown, b: unknown): boolean => {
  if (typeof a !== 'number' || typeof b !== 'number') {
    return false;
  }

  return a <= b;
};

const isSomeModel = (obj: unknown): obj is SomeModel => {
  return obj instanceof SomeModel;
};

/**
 * __Is Less Than Or Equal To__ validation function
 */
const IsLte = createCustomValidator<SomeModel>(
  'isLte',
  isLessThanOrEqualTo,
  isSomeModel
);

export class SomeModel {
  @IsNumber()
  @Min(1, { message: 'minimum points should be positive nonzero number' })
  totalPoints!: number;

  @IsNumber()
  @Min(1, { message: 'minimum points should be positive nonzero number' })
  @IsLte('totalPoints', {
    message: 'Obtained points must be less than or equal to total points'
  })
  obtainedPoints!: number;
}

In addition, here is a basic test scenario for validation purposes:

  import 'reflect-metadata';
  import { validate, ValidationError } from 'class-validator';

  describe('obtainedPoints', () => {
    it('should throw an error when the obtainedPoints exceed the total points', async () => {
      const model = new SomeModel();

      model.totalPoints = 10;
      model.obtainedPoints = 20;

      const result = await validate(model, {
         forbidUnknownValues: true
      });

      expect(result.length).toBe(1);
      expect(result[0].property).toBe('obtainedPoints');
      expect(result[0].constraints?.isLte).toBeTruthy();
    });
  });

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

The state is not being updated immediately when trying to set the state in this React component

Currently, I am working on a React component that is listening to the event keypress: import * as React from "react"; import { render } from "react-dom"; function App() { const [keys, setKeys] = React.useState<string[]>([]); ...

What is the best way to trigger an API call every 10 seconds in Angular 11 based on the status response?

I am in need of a solution to continuously call the API every 10 seconds until a success status is achieved. Once the success status is reached, the API calls should pause for 10 seconds before resuming. Below is the code I am currently using to make the A ...

What is the proper method for typing unidentified exports that are to be used in TypeScript through named imports?

Currently, I am developing an NPM package that takes the process.env, transforms it, and then exports the transformed environment for easier usage. The module is structured like this: const transformedEnv = transform(process.env) module.exports = transf ...

Tips for resolving the issue: 'Unhandled Promise Rejection: Error: Unable to resolve bare specifier "app.js" from http://localhost:3000/'

While delving into TypeScript, I have come across an error related to node modules. https://i.sstatic.net/IPx5A.png Upon clicking the anonymous function, it leads me to the following code snippet. https://i.sstatic.net/4U8dY.png <!DOCTYPE html> & ...

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 ...

Develop Connective Plugins using Angular 12

I am working on implementing a new feature for my app that involves storing certain modules on the backend and loading them dynamically based on user demand. Instead of loading all modules at once, I want to only load the necessary modules just before the ...

Encountering SSR crashes in Next.js when a GraphQL request fails (resulting in an HTTP code 500) while utilizing Apollo

Hey there, I'm feeling a bit overwhelmed. Let me try to explain my situation as clearly as possible. I'm currently using Apollo client for my GraphQL queries along with NextJS. I have a page that needs to be server-side rendered for SEO purposes ...

Using Angular: How to set the index value from a dropdown to a local variable after a button is clicked

Can someone please provide guidance on how to assign the index value (i = index) to EmployeeIndex: any; after a button click event? Your suggestions are greatly appreciated. Here is my code: HTML <select class="form-control" [(ngModel)]="EmployeeNam ...

Come back to Angular 2 on your return function

Having a problem with an asynchronous function. There is a service that retrieves data from a Firebase database. One of the functions returns a value: historialDeConsumi() { this.item = this.af.database.object('/users/' + this.uid + '/a ...

What is the best way to test the validity of a form while also verifying email availability?

I am currently working on implementing async validation in reactive forms. My goal is to disable the submit button whenever a new input is provided. However, I am facing an issue where if duplicate emails are entered, the form remains valid for a brief per ...

Explicit final argument in TypeScript

Is it feasible to define a function in TypeScript 2.7.2 and above with variable parameters, but ensuring that the final parameter has a specific type? I am attempting to craft an ambient TypeScript declaration for a JavaScript library that utilizes functi ...

How to render a markdown file from a specified path using React and TypeScript

I am currently working on setting up routes to different .md files within my react/typescript application. Inside my App.tsx file, I have the following code: <Router> <main> <nav className="navbar navbar-expand-md navbar-light bg ...

Looking for a more efficient approach to writing React styles for color?

Desire I am interested in customizing colors within Material UI components. Moreover, I aim to develop a React Component that allows for dynamic color switching through Props. Challenge The current approach using withStyles results in redundant and lengt ...

Troubleshooting Angular Build Errors: Integrating Three.js

Upon setting up a new Angular application and integrating three along with @types/three, I proceeded to create a basic component. However, upon executing ng build --prod, the following errors are displayed: ERROR in node_modules/three/src/core/BufferAttri ...

Is there support for TypeScript in express-openid-connect?

Is there any documentation available for using express-openid-connect with TypeScript, or if it is supported at all? ...

Learn how to activate the explorer tab and include an authorization prefix in the GraphiQL playground

What is the process for adding a prefix (e.g. "Authorization" : null ) in graphiql playground? How can I activate the explorer tab to access available query and mutations? ...

Exploring the capabilities of using the injectGlobal API from styled-components in a TypeScript

I've been attempting to utilize the simple injectGlobal API, but I am encountering difficulties getting it to work with TypeScript. Here is my setup in theme.tsx: import * as styledComponents from "styled-components"; import { ThemedStyledComponentsM ...

Tips for updating a JSON object value in Node.js

Storing a JSON object in a JSON file is important for passing data during an API call. To update the object, replace "it-goes-here" with the following {} block. Newly updated data: { "parenturl":"xxx.com", "user ...

The error message "Property 'data1' is not a valid property on the object type {}"

const Page: NextPage = ({data1}:{data1:any}) => { const [open, setOpen] = React.useState(false); const [data, setData] = React.useState(data1); const handleAddClick = () => { setOpen(true); }; ..... } export async function getServerS ...

Ensure the JSON file aligns with the TypeScript Interface

I am working with a config.json file. { "profiler": { "port": 8001, "profilerCache": { "allowedOriginsRegex": ["^http:\/\/localhost:8080$", "i"] } }, "database": { "uri": "mongodb+srv://...", "dbName": "profiler", ...