Creating a personalized validation tool using regular expressions in AngularJS version 2.2.4

Let me present the challenge at hand:

I am currently working on developing a "custom validator" for password and email fields using AngularJS v2. The structure of my project involves multiple files interacting with each other:

/forms/form.component.ts
/validators/password.validator.ts
/validators/email.validator.ts

In the template of my form component, I have the following setup for the password and email fields:

//...
<input type="password" class="form-control" placeholder="password" [(ngModel)]="user.password" [formControl]="passwordCtrl" required />
<div *ngIf="passwordCtrl.dirty && passwordCtrl.hasError('validPassword')">PASSWORD NOT VALID</div>
//...
<input type="text" class="form-control" placeholder="email" [(ngModel)]="user.email" [formControl]="emailCtrl" required />
<div *ngIf="emailCtrl.dirty && emailCtrl.hasError('validemail')">EMAIL NOT VALID</div>
//...

Within the component (.ts) file, my implementation is as follows:

//...
import { validateEmail } from '../validators/email.validator';
import { validatePassword } from '../validators/password.validator';
//...in constructor(fb: FormBuilder) : 
this.passwordCtrl = fb.control(this.user.password, Validators.compose([validatePassword])),
this.emailCtrl = fb.control(this.user.email, Validators.compose([validateEmail])),
//...

The declarations and instantiations in my component.ts seem correct because when I include a "required" validator in the "compose." part, it functions properly. However, there seems to be an issue with the validator logic itself. Here are the validators:

//email.validator.ts
import { FormControl } from '@angular/forms';
export function validateEmail(c: FormControl){
    let EMAIL_REGEXP = new RegExp(`([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)+`);
    return EMAIL_REGEXP.test(c.value) ? null : {
        validateEmail: {
            validemail: false
        }
    };
}

//password.validator.ts
import { FormControl } from '@angular/forms';
export function validatePassword(c: FormControl) {
    let PASSWORD_REGEXP = new RegExp(`^.*(?=.{6,20})(?=.*\d)(?=.*[a-zA-Z]).*$`);
    return PASSWORD_REGEXP.test(c.value) ? null : {
        validatePassword: {
            validpassword: false
        }
    };
}

You can find more information about custom validators here.

Despite tweaking the return values of "validpassword" or "validemail," the divs dependent on the validateemail and validatepassword validators never appear.

Any insights or assistance would be greatly appreciated.


Update 1 :

My objective is to create forms for both login and register functionalities within the same page. I have successfully set up 2 formGroups in my form.component.ts:

//...
this.loginForm = fb.group({
    login: this.loginCtrl,
    password: this.passwordCtrl
}),
this.registerForm = fb.group({
    login: this.loginCtrl,
    password: this.passwordCtrl,
    email: this.emailCtrl
});

Each form is associated with its respective formGroup, which are linked in the template as shown below (with submit buttons included):

//...
<form (ngSubmit)="register()" [formGroup]="registerForm">
//...
<button class="btn btn-default submit" [disabled]="!registerForm.valid">Submit</button>
//...
//...
<form (ngSubmit)="login()" [formGroup]="loginForm">
//...
<button class="btn btn-default submit" [disabled]="!loginForm.valid">Login</button>

However, I have noticed that both buttons remain disabled unless all the fields are filled out. For instance, if the email field is left empty in the "registerForm" group, then the "Login" button in the "loginForm" group also remains disabled.

Shouldn't formGrouping handle such scenarios automatically?

Answer №1

One way to ensure better email validation is by replacing hasError('validemail') with hasError('validateEmail'). This will accurately reflect the property of the error object returned from the validator.

Additionally, it's recommended to create new instances of FormControl for your form components:

this.loginFormLoginCtrl = new FormControl('', Validators.required);
this.loginFormPasswordCtrl = new FormControl('', Validators.required); 
this.registerFormLoginCtrl = new FormControl('', Validators.required); 
this.registerFormPasswordCtrl = new FormControl('', Validators.required); 
this.registerFormLoginCtrl = new FormControl('', Validators.required);

    ....
this.loginForm = fb.group({
     login: this.loginFormLoginCtrl,
     password: this.loginFormPasswordCtrl
});
this.registerForm = fb.group({
     login: this.registerFormLoginCtrl,
     password: this.registerFormPasswordCtrl,
     email: this.registerFormEmailCtrl
});

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

Obtain environment variables within a Strapi plugin

I am currently working on developing a Strapi local plugin, but I am facing an issue with retrieving variables defined in my .env file located at the root of my project. Specifically, I am trying to access this value within my React component (plugins/myPl ...

A step-by-step guide to dynamically adding HTML content on a button click using AngularJS

Can HTML content be added on Button Click event using AngularJS? Here is the code from my index.html: <div class="form-group"> <label for="category"> How Many Questions Do You Want to Add? </label> <div class="col-sm-10"& ...

What sets Fetch apart from ajax and XMLHttpRequest that makes it impressively faster?

Over the past few days, I have been working on optimizing a client table for a project. The table contains over 10k clients, and as a result, it was taking a long time to load. The front-end team had implemented pagination, filters, and reordering, which ...

Detecting a mobile device when using NextJS can be accomplished by using user

With so many topics and questions on Stack Overflow, I am struggling to find the most efficient solution for detecting mobile devices. I have two components - one designed solely for desktops and another for mobile devices. {isMobile? (<SecondComponen ...

Exploring the dynamic attributes of an Object in React

My task involves checking for the presence of a placeholder in the "all" string within the alertDetails object. I specifically need to access the email, sms, and fax properties which are generated dynamically based on user input (this code is part of an al ...

Angular is throwing an error message stating that it cannot find a differ that supports an object of type 'object'. NgFor only supports binding to iterables like Arrays

I am currently in the process of developing an Angular application that displays a list of projects and users from a PostgreSQL database. However, I have encountered difficulties when trying to display the list of users in HTML. The issue seems to be that ...

Guide to displaying a loading message while performing a synchronous AJAX request in a web browser

Is there a way to display a waiting message during a synchronous AJAX call in the browser? I attempted to use the code below, but even after turning off the web server, the "Saving" message did not appear. After some time, only an error event from the AJA ...

Avoiding redundant API requests in transclusion by ensuring that only one instance of the duplicated component is displayed

In my Angular project, I am utilizing transclusion to create a fixed view template with slots for dynamic content. The component I'm working with is called app-filter-details and here is its template: <div id="details-wrapper"> <div cla ...

Using jQuery to extract information from a JSON data structure

My JSON data consists of different types of cards, each with a type, number, and URL: { "cards": [ { "type": "Cultural", "number": "auto", "url": "http://www.url1.com" }, { "type": "Museums", "number": "auto", ...

Utilizing a backup system to store environment variables within a configuration file

Currently, I am utilizing my environment variables by directly referencing process.env.NODE_ENV throughout my application. While this method works, it is becoming challenging to manage and keep track of. Therefore, I would like to consolidate all these var ...

Can you explain the significance behind the error message "RangeError: Invalid status code: 0"?

Currently, I'm trying to understand the workings of express and have come up with this get method: app.get('/myendpoint', function(req, res) { var js = JSON.parse ({code: 'success', message:'Valid'}); res.status( ...

Error message: NullInjectorError: R3InjectorError[ToastrService -> ToastrService -> InjectionToken ToastConfig -> InjectionToken ToastConfig]:

I'm struggling with integrating ngx-toastr into my Angular standalone micro-frontend in angular 16. When I try to add the ngx-toastr provideToast() function in the main Module component, it doesn't seem to work as expected. Can someone please hel ...

Exploring the possibilities of using jQuery to access global variables in node.js

My issue has 3 main components. I need to declare a server-side (node.js) variable to store data for the duration of the server run, specifically just a number. I must send a number from the client (jQuery) to the server in order to update the server v ...

Mapping out your data effectively requires following the correct steps to ensure accuracy and clarity

My goal is to display a map using Mapbox only once the data is ready. The Vuex store code I am working with is as follows: /store/index.js import Vue from "vue"; import Vuex from "vuex"; import _ from "lodash"; import { bac ...

Unlock the Power of TWBS Ratchet: Manually Closing Modal Windows

Currently, I am in the process of developing a mobile web application using Ratchet. The main task at hand involves opening a modal, filling out a form, clicking a button to save the input data, and then closing the modal. Although I have managed to close ...

Ensure that the injected service's constructor has completed before running tests in Karma 4 with Angular 7

I'm including a service in this manner: it('test name', inject([ Service], (hcs: Service) => { const pipe = new MyPipe(hcs); const expectedResult = ... //The constructor of the hcs-service must be completed before executing t ...

When a button is clicked within ng-repeat, the alert displays an incorrect value

Greetings! Check out my code below for displaying XML data in an HTML table using AngularJS. Each record includes a "Delete Request" button. Here is the HTML code: <div ng-app="myApp" ng-controller="myCtrl"> <table border="1" width=" ...

Press Button to create cookie and store it in Drupal 7

I am currently working on my Drupal 7 local website, which features an article and a popup on the homepage leading to that article. Within the article, there is a button that I want to serve as a way for users to dismiss the initial popup permanently. My i ...

Displaying PHP/Json Data in Angular2 with Loops

Hello there! I am new to Angular and have been trying to work through a problem with the help of some guides. However, I still feel like I could use some assistance from you. Here's what I've accomplished so far: I have set up a button that tri ...

Is there a way to convert this asynchronous function into a synchronous one so that it returns the value immediately

When it comes to making a Nodejs/Javascript method synchronous, there are several solutions offered by the community. Some suggest using libraries like async and fibrous, but these involve wrapping functions externally. However, I am in search of a soluti ...