Steps for creating a personalized function for a specified custom rule within Aurelia Validation

I am currently utilizing aurelia-validation and have developed a custom rule.

Logic for Rule Validation:

export function validateCompare(value: any, obj: any, otherPropertyName: string) {
    return value === null ||
        value === undefined ||
        value === "" ||
        obj[otherPropertyName] === null ||
        obj[otherPropertyName] === undefined ||
        obj[otherPropertyName] === "" ||
        value === obj[otherPropertyName];
}

Configuration:

import { ValidationRules, validationMessages } from "aurelia-validation";
import { validateCompare } from "./compareValidation";

export function configureValidation() {
    validationMessages["required"] = "${$displayName} is required";
    validationMessages["email"] = "${$displayName} is in an invalid format";

    ValidationRules.customRule("compare", validateCompare, "${$displayName} does not match ${$getDisplayName($config.otherPropertyName)}", otherPropertyName => ({ otherPropertyName }));
}

Usage of the Custom Rule:

ValidationRules
    .ensure((m: ClienteEdicaoViewModel) => m.Login).required().satisfiesRule("login")
    .ensure((m: ClienteEdicaoViewModel) => m.Senha).satisfiesRule("requiredIf", "ConfirmacaoSenha").satisfiesRule("senha")
    .ensure((m: ClienteEdicaoViewModel) => m.ConfirmacaoSenha).displayName("Confirmation Password").satisfiesRule("requiredIf", "Senha").satisfiesRule("compare", "Senha")
    .on(ClienteEdicaoViewModel);

Inquiry:

I am working with typescript and would like to create a method that simplifies the use of the satisfiesRule. I want to apply rules as follows:

ValidationRules
    .ensure((m: ClienteEdicaoViewModel) => m.Login).required().login()
    .ensure((m: ClienteEdicaoViewModel) => m.Senha).requiredIf("ConfirmationPassword").password()
    .ensure((m: ClienteEdicaoViewModel) => m.ConfirmationPassword).displayName("Confirmation Password").requiredIf("Password").compare("Password")
    .on(ClienteEdicaoViewModel);

Is there a way to create the requiredIf and compare methods and incorporate them into the FluentRule?

C# has extension methods that could achieve this, but my attempts in TypeScript have been unsuccessful so far.

Answer №1

To enhance the validation module, you must extend the prototype with the necessary implementation. Below is an example of how your configuration should be set up.

import { ValidationRules, validationMessages, FluentRuleCustomizer, FluentRules } from "aurelia-validation";
import { validateCompare } from "./compareValidation";

export function configureValidation() {
    validationMessages["required"] = "${$displayName} is required";
    validationMessages["email"] = "${$displayName} is in an invalid format";

    ValidationRules.customRule("compare", validateCompare, "${$displayName} does not match ${$getDisplayName($config.otherPropertyName)}", otherPropertyName => ({ otherPropertyName }));
}

declare module "aurelia-validation/dist/commonjs/implementation/validation-rules" {
    interface FluentRules<TObject, TValue> {
        compare(value: string): FluentRuleCustomizer<TObject, TValue>;
    }

    interface FluentRuleCustomizer<TObject, TValue> {
        compare(value: string): FluentRuleCustomizer<TObject, TValue>;
    }
}

FluentRules.prototype.compare = function (value: string) {
    return this.satisfiesRule("compare", value);
};

FluentRuleCustomizer.prototype.compare = function (value: string) {
    return this.satisfiesRule("compare", value);
};

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

Is it necessary to meticulously cycle through every value in the string combination?

So, I am working with a string union that looks like this: export type Intervals = 'total' | 'weekly' | 'biweekly' | 'monthly' | 'annually'; To show these options to the user, I plan on iterating over an ...

Angular FormControl is a built-in class that belongs to the Angular forms module. It

I’ve been working on adjusting tslint for the proper return type, and here’s what I have so far: get formControls(): any { return this.form.controls; } However, I encountered an error stating Type declaration of 'any' loses type-safet ...

Dependency injection in Angular is a powerful design pattern that

I recently completed an Angular 2 website, but I've run into some issues that I cannot seem to debug. I've spent the past week trying to find a solution but have had no luck. Below, I've included some snippets of my code. Feel free to ask fo ...

Encase a function with an observable

In my bd service, there is a method called consultaPublicacoes that retrieves all publications from the Firebase database for a specific user email. bd.service public consultaPublicacoes(email:string):Observable<any>{ return this.checkarPu ...

The axios GET request failed to return a defined value

My current issue involves making a get request using the following code snippet: router.get('/marketUpdates',((request, response) => { console.log("market updates"); var data: Order[] axios.get('http://localhost:8082/marketUpdates& ...

Using TypeScript to Return a Derived Class as a Method's Return Type

I'm currently facing a challenge with an abstract class in typescript that includes a method to provide a callback for later use. The issue lies in the return type of the method, as it is set to the class itself, preventing me from using fluent style ...

Where should the API call be placed in the app.component to halt the system until the response is received and injected into the body, instead of using ngOnInit?

I am currently exploring Angular and experimenting with various features. Recently, I encountered an issue that requires me to take certain actions based on the results returned by a service before the application fully loads. Currently, I am making a cal ...

Organize JSON data in Angular 6 from an observable based on a specific key

Note: While I am familiar with sorting a regular array of objects using .sort(), I am facing a challenge with an observable object that I am not accustomed to. My task involves retrieving a JSON array of objects with a service: import { Injectable } from ...

How to remove the border of the MUI Select Component in React JS after it has been clicked on

I am struggling to find the proper CSS code to remove the blue border from Select in MUI after clicking on it. Even though I managed to remove the default border, the blue one still persists as shown in this sandbox example (https://codesandbox.io/s/autumn ...

The type '{ }' does not include the properties 'params', 'isExact', 'path', 'url' from the 'match<Identifiable>' type

Currently, I am utilizing react router and typescript in order to extract the id variable from a route for use in a component. However, typescript is raising an issue: The type '{}' lacks the following properties found in type 'match' ...

Is there a way to manipulate the parent HTML element based on the output value sent to my component?

Within my codebase, I am utilizing two components - HrComponent and appcomponent. How can I effectively manage the boolean value IsBoolean from my HrComponent? HrComponent @Input()LoginName: string; IsBoolean: boolean = false; @Output()BooleanExp: ...

Tips for bringing in an enum from TypeScript?

I am working with a module defined in TypeScript that looks like this: declare module MyTypes { export enum MyEnum { GOOD = 'Good', BAD = 'Bad', UNKNOWN = '-' } export interface MyType1 { ...

Using agSelectCellEditor to populate Angular Grid dropdowns with values from a database

Utilizing refData and agSelectCellEditor in Angular 8 to display dropdown values during editing. I found a solution at the following link: https://www.ag-grid.com/javascript-grid-reference-data/ However, the dropdown list data is fetched from the Databas ...

The primeng MenuItem component does not have a 'command' property and is of type 'never'

I am currently working on implementing a primeng ContextMenu using the Menu Model API. Within the MenuItem object, there is a property named "command" which, to my understanding, should be a function. As I am receiving the available context menu items fro ...

Angular: Discover the best way to delegate translation tasks to your S3 bucket!

I am currently using ngx-translate for handling translations in my Angular application. Everything is functioning properly when the translation files are stored within the app itself. However, I want to move all of my JSON translation files to an AWS S3 bu ...

Is there a distinction between Entity[] and array<Entity> in TypeScript?

Everything in the title, for example people: Person[]; people: Array<Person>; What sets them apart? Is there a preferred approach? Note: I couldn't find any guidance on this and I've encountered both in code. ...

Tips for managing errors when using .listen() in Express with Typescript

Currently in the process of transitioning my project to use Typescript. Previously, my code for launching Express in Node looked like this: server.listen(port, (error) => { if (error) throw error; console.info(`Ready on port ${port}`); }); However ...

Receiving an error in Angular 7: Unable to retrieve value from child component as it is returning Undefined

I am looking for a way to transfer a value between components so that I can switch from a list of candidates to another panel where I can edit the selected candidate. Unfortunately, I encountered an error: ERROR TypeError: "this.listCandidateComponent is ...

What could be the reason for the esm loader not recognizing my import?

Running a small express server and encountering an issue in my bin/www.ts where I import my app.ts file like so: import app from '../app'; After building the project into JavaScript using: tsc --project ./ and running it with nodemon ./build/bin ...

Retrieving Age from HTML5 Date Input in Angular 2+

I need assistance in calculating the age from a date input in an existing form using HTML5 and Angular. I want to achieve this without requiring the user to click anything. Although I am able to retrieve the date, the format is causing issues with my code ...