Hone logo
Hone
Problems

Angular Custom Validator Directive: Email Format Enforcement

This challenge focuses on creating a reusable custom directive in Angular to validate the format of an email address input field. Implementing custom validation logic directly within components can lead to code duplication. A custom directive provides a clean, declarative way to enforce validation rules across your Angular application, improving maintainability and reusability.

Problem Description

You need to create a custom Angular directive that acts as a validator for an email address input field. This directive should leverage Angular's built-in Validator interface to integrate seamlessly with Angular's forms module.

Key Requirements:

  1. Directive Creation: Create a new Angular directive.
  2. Email Validation Logic: Implement the validate method from the Validator interface to check if the input value is a valid email address format. A simple regex can be used for this validation.
  3. Integration with Forms: The directive should be registered as a validator with Angular's forms system. This means it should be able to be applied to FormControls or NgModels.
  4. Error Reporting: When the input value is not a valid email format, the directive should return an error object (e.g., { invalidEmail: true }).
  5. No Error on Valid Input: When the input value is a valid email format or is empty (allowing optional fields), the directive should return null.

Expected Behavior:

When the directive is applied to an input element:

  • If the input is empty, no validation error should be reported.
  • If the input contains a string that resembles a valid email address (e.g., "test@example.com"), no validation error should be reported.
  • If the input contains a string that does not resemble a valid email address (e.g., "invalid-email", "test@.com"), a validation error with a specific key (e.g., invalidEmail) should be reported.

Edge Cases to Consider:

  • Empty Input: The directive should gracefully handle empty input values, typically by not marking them as invalid.
  • Case Sensitivity: Email addresses are generally case-insensitive for the local part, but the directive's regex should account for this, or the validation should normalize the input if necessary (though for simplicity, a regex that handles common formats is sufficient here).

Examples

Example 1: Valid Email Input

Input Value: "user.name123@sub.domain.co.uk"
Validation Result: null (No error)
Explanation: The input value is a well-formed email address.

Example 2: Invalid Email Input

Input Value: "invalid-email-address"
Validation Result: { invalidEmail: true }
Explanation: The input value does not conform to a typical email address structure (missing '@' and domain).

Example 3: Empty Input

Input Value: ""
Validation Result: null (No error)
Explanation: Empty input is considered valid by default for optional fields.

Example 4: Partially Invalid Email

Input Value: "test@.com"
Validation Result: { invalidEmail: true }
Explanation: The domain part of the email is malformed.

Constraints

  • The directive must be implemented in TypeScript.
  • The directive should be compatible with Angular versions 9+.
  • The primary validation logic should be encapsulated within the directive itself.
  • The directive should return a specific error object { invalidEmail: true } when validation fails.
  • Performance is not a critical concern for this simple regex-based validation, but the implementation should be efficient.

Notes

  • You will need to import Validator and AbstractControl from @angular/forms.
  • The directive will need to be provided in the providers array of your Angular module or component.
  • Consider using a regular expression that covers common email formats. A comprehensive RFC-compliant regex can be overly complex for this exercise.
  • Remember to import Directive from @angular/core.
  • To use the directive in a template, you'll typically apply it as an attribute to an <input> tag. For example: <input type="email" appEmailValidator ...>.
Loading editor...
typescript