Ways to extract a validator function from a text input

How can I transform this string array into an array of validator functions?

let valStrings: string[] = ["Validators.required", "Validators.maxLength(10)"];

Convert it to:

let validators: ValidatorFn[] = [ Validators.required, Validators.maxLength(10) ];

I am working on centralizing validation rules for our web application to ensure consistency between server and client validation. These strings are retrieved from a HttpClient call with a JSON response.

The array of validators will be used in a FormControl to enable reactive form validation in Angular.

Should I consider using eval() in this scenario?

Thanks -Adam

Answer №1

It is not recommended to define validation on the server using Angular code in a string format. Instead, consider creating an API for handling dynamic validations like this:

validations: {
  name: {
    maxLength: 10,
    required: true
  }
}

Using eval for this purpose is not advisable as it introduces security risks and may be disabled on your site by Content Security Policy (CSP).

Avoid converting strings to code directly as it would require a parser. If Angular's validation rules change, you would need to update all forms accordingly.

Furthermore, if you plan to connect an iOS app to your API, parsing Angular validation rules from strings can be cumbersome and error-prone.

Answer №2

In order to achieve this, I rely on the use of conditional statements.

let valStrings: string[] = ["Validators.required", "Validators.maxLength(10)"];
let validators=valString.map(x=>{
    switch (x)
    {
        if (x=="Validators.required")
            return Validators.required;
        if (x.startsWith("Validators.maxLength")
        {
            let length=+(x.split('(')[1].split(')')[0]);
            return Validators.maxLength(length)
        }
    }
});

Answer №3

A map of validation can be easily implemented within an abstracted service for reusability purposes.


export const schema = {
    "defaultValidations": {
        'title': [
            { name: 'required' },
            { name: 'minLength', args: [3] }
        ],
        'firstName': [
            { name: 'required' },
            { name: 'minLength', args: [3] },
            { name: 'maxLength', args: [50] }
        ]
    }
}

export interface Dictionary<T> {
    [Key: string]: T;
}

  validationMap: Dictionary<any> = {
    "required": (arg: any[]) => Validators.required,
    "minLength": (arg: number[]) => Validators.minLength(arg[0]),
    "maxLength": (arg: number[]) => Validators.maxLength(arg[0])
  };

  constructor(private fb: FormBuilder) { }

  // function to map validations
  mapValiations(key: string) :ValidatorFn[] {
    const validations = schema.defaultValidations[key]?.map(element => {
        return this.validationMap[element.name](element?.args);
     });

     return validations;
  }

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

Utilizing TypeScript in an AngularJS (1.x) project alongside Webpack: A Step-By-Step Guide

Currently, I am working through the official guide on transitioning from AngularJS (1.x) to Angular (2+). I have successfully divided my application into Components and integrated ES6 with Webpack as the module loader. However, I now find myself unsure of ...

Error encountered when performing Change Detection in Angular Material with ngOnChanges, displaying message, "ExpressionChangedAfterItHasBeenCheckedError"

One of the challenges I'm facing is displaying an Input property for a component only if the current data is not undefined. To detect changes, I have implemented ngOnChanges but encountered an error message "ExpressionChangedAfterItHasBeenCheckedErro ...

Required Ionic form field alert

Currently, I am developing a new app using ionic 3 and I am facing an issue with making inputs mandatory in my ionic-alert controller. Despite going through the ionic-component documentation and api documentation, I couldn't find a solution on how to ...

skipSelector is not recognized

While attempting to create a new component in Angular, I encountered the following error: ng g c contact-us Your global Angular CLI version (8.1.1) is greater than your local version (7.1.4). The local Angular CLI version is used. To disable this warning ...

Resolving the Issue: How to Solve the "Missing Required Request Body" Error in Angular and Spring MVC

I'm encountering an issue with removing a product from the database using Angular on the frontend. The error message I am receiving is: Required request body is missing: public boolean prodcust.controller.DeleteController.deleteProduct(java.lang.Stri ...

using lodash to convert objects into arrays while maintaining parent-child relationships

Is there a way to achieve this transformation in lodash or any other JavaScript/TypeScript method? var obj = { a: [ {id:1},{id:2},{id:3}] b: [ {id:4},{id:5},{id:6}] c: [ {id:7},{id:8},{id:9}] } // Need to transform into var arr = [ {title:a ...

Dependencies exclusively for NPM post-installUnique Rewrite: "N

I have been using git to distribute an internal TypeScript NPM package. To avoid cluttering my repository with build files, I have implemented a postinstall action to build the package upon installation: "postinstall": "tsc -p tsconfig.json& ...

Remove default focus from angular 2 material input field

Currently, I am faced with a dialog containing a text input, radio buttons, and ok cancel buttons. Upon opening the dialog, the cursor automatically blinks inside the text input, causing the placeholder text to zoom out and become difficult to read. The ...

Encountering an error stating "unable to access properties of undefined (reading 'redirectUri')"

I am currently working on fetching details from Okta and saving them in a Store. My code includes an @effect that triggers a service file named a-service.ts. Inside the service constructor, I call the Okta library as shown below: @Injectable() export clas ...

What kind of null/undefined is being assumed?

system details: Visual Studio Code Version: 1.47.3 Typescript Version: 4.0.0-dev.20200727 tsconfig.js: "strict": true, code example: let x = null; // x is any type let y = x; // x is null type(why? x is any type on top), y is null type x = 1; / ...

Maintain a continuous live server for your Angular 2/4 application

Is there a way to run an Angular application permanently? When I run the npm start command on a local server, it provides a URL with a port such as localhost:4200. However, when I close the terminal, the project stops running. The same issue occurs when ...

ng serve issue persists even after resolving vulnerabilities

Can anyone assist me in resolving why I am unable to start my project after fixing 3 high vulnerabilities? I ran npm audit to identify the vulnerabilities and then used npm install --save-dev @angular/<a href="/cdn-cgi/l/email-protection" class="__cf_em ...

What is the correct way to access $auth in Nuxt with TypeScript?

<script lang="ts"> import LoginAdmin from '@/components/LoginAdmin.vue' import { Component, Vue } from 'nuxt-property-decorator' import Auth from "@nuxtjs/auth"; export default class MyStore extends Vue { pub ...

How can you prevent specific dates from being selected in an Angular Datepicker?

Is there a way to exclude Monday from the "mat-datepicker" component? I've tried implementing the following code in my class component: dateFilter = (_date: any) =>{ let day = _date.getDay(); console.log(day); return day != 1; ...

Navigating the NextJS App Directory: Tips for Sending Middleware Data to a page.tsx File

These are the repositories linked to this question. Client - https://github.com/Phillip-England/plank-steady Server - https://github.com/Phillip-England/squid-tank Firstly, thank you for taking the time. Your help is much appreciated. Here's what I ...

Is there a way to remove a specific column from a table in Angular?

I am looking to develop a dynamic table that allows users to add rows and columns. Additionally, I want the functionality to delete selected columns from the table. You can view my project on Stack Blitz here: https://stackblitz.com/edit/delete-selected-co ...

The parameter of type 'void' cannot be assigned to a parameter of type 'SetStateAction<never[]>' in this context

Looking to retrieve data from a firestore collection using TypeScript, but encountered an error when following the JavaScript example provided. The error occurred at setBookmark(querySnapshot.forEach((doc) => { React.useEffect(() => { const getB ...

Increasing the token size in the Metaplex Auction House CLI for selling items

Utilizing the Metaplex Auction House CLI (ah-cli) latest version (commit 472973f2437ecd9cd0e730254ecdbd1e8fbbd953 from May 27 12:54:11 2022) has posed a limitation where it only allows the use of --token-size 1 and does not permit the creation of auction s ...

Mapping objects in Typescript to create a union of objects

I have been working on some TypeScript code and I seem to be having trouble getting it to work as expected. It would be greatly appreciated if someone could help me understand what I'm doing wrong or suggest a different approach. Let's assume I ...

Combining data types to create a unified set of keys found within a complex nested structure

This problem is really testing my patience. No matter what I do, I just can't seem to make it work properly. Here's the closest I've come so far: // Defining a complex type type O = Record<'a', Record<'b' | 'x& ...