Utilizing $asyncValidators in angularjs to implement error messages in the HTML: A guide

This is my first major form with validations and more. I've set up a Registration form and I'm utilizing ng-messages for validation. The issue arises when I have to check the username, whether it already exists in the JSON server we are using or if it's available. If it's taken, a warning message appears in the HTML near the username input; if it's available, the submit button becomes enabled (as the form will be $valid) allowing the user to proceed with the registration process. I intend to use angular-sanitize because I discovered this snippet of code:

    ngModel.$asyncValidators.uniqueUsername = function(modelValue, viewValue) {
      var value = modelValue || viewValue;

      // Looking up user by username
      return $http.get('/api/users/' + value).
         then(function resolved() {
           // Username exists, meaning validation fails
           return $q.reject('exists');
         }, function rejected() {
           // Username does not exist, therefore this validation passes
           return true;
         });
    };

Below is the current code I am using (registration form, controller, and service):

// Controller:
export default class registerPageController {
  constructor(userService, authenticationService, $location) {
    this.register = "Register";
    this.userService = userService;
    this.$location = $location;
    this.authenticationService = authenticationService;
    this.hasLoggedIn = false;
  }

  onSubmit(user) {
    let self = this;
    let {
      name,
      age,
      email,
      username,
      password
    } = user;
    self.userService.register(name, age, email, username, password).then((res) => {
        self.userService.login(username, password).then(function (response) {
          let data = response.data;

          if (data.length) {
            let user = data[0];
            self.hasLoggedIn = true;
            self.authenticationService.setCredentials(username, password);
            self.$location.path('/');
          }
        });
      })
      .catch(err => {
        // WHAT TO PUT HERE AFTER THE USERNAME EXISTS VALIDATION ?
      })
  }
}

// Service:

export class UserService {
  constructor($http) {
    this.$http = $http;
  }

  login(username, password) {
    return this.$http({
      method: 'GET',
      url: 'http://localhost:3000/users',
      params: {
        username: username,
        password: password
      }
    });
  }

  register(name, age, email, username, password) {
    return this.$http({
      method: 'POST',
      url: 'http://localhost:3000/users',
      data: {
        name: name,
        age: age,
        email: email,
        username: username,
        password: password
      }
    });
  }

// SHOULD I PUT THE USERNAME EXISTS VALIDATION LOGIC HERE?

}
<div class="container main-content">
  <form class="registrationForm" name="registerForm" ng-submit="register.onSubmit(register.user)" novalidate="novalidate">

    <!-- Enter Name -->
    <div class="form-group">
      <label for="name" class="control-label"><span id="reqInfo">*</span> Name</label>
      <input type="text" name="name" class="form-control" ng-model="register.user.name" ng-pattern="/[a-zA-Zа-яА-Я]+/" id="name"
        required="" placeholder="Example: Petar Petrov">
      <div ng-messages="registerForm.name.$error" ng-show="registerForm.name.$touched" style="color:maroon" role="alert">
        <div ng-message="required">Your name is required</div>
      </div>
    </div>

    <!-- User Age-->
    <div class="form-group">
      <label for="age" class="control-label"><span id="reqInfo">*</span> Age</label>
      <input type="number" name="age" class="form-control" ng-model="register.user.age" ng-min="18" min="18" id="age" required=""
        placeholder="Enter your age">
      <div ng-messages="registerForm.age.$error" ng-show="registerForm.age.$touched" style="color:maroon" role="alert">
        <div ng-message="min">You must be at least 18 years old</div>
      </div>
    </div>

    <!-- Enter E-mail -->
    <div class="form-group">
      <label for="email" class="control-label"><span id="reqInfo">*</span> E-mail</label>
      <input type="email" name="email" class="form-control" ng-model="register.user.email" ng-pattern="/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)/"
        id="email" required="" placeholder="Example: <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6805090104280509010446060d1c">[email protected]</a>">
      <div ng-messages="registerForm.email.$error" ng-show="registerForm.email.$touched" style="color:maroon" role="alert">
        <div ng-message="required">Your valid e-mail is required</div>
      </div>
      <br>

      <!-- Enter Username -->
      <div class="form-group">
        <label for="username" class="control-label"><span id="reqInfo">*</span> Username</label>
        <input type="text" name="username" ng-minlength="5" ng-maxlength="20" class="form-control" ng-model="register.user.username"
          ng-pattern="/^[A-Za-z0-9_]{1,32}$/" ng-minlength="7" id="username" required="" placeholder="Enter your username">     
        <div ng-messages="registerForm.username.$error" style="color:maroon" role="alert">
          <div ng-message="minlength">Your Username must be between 7 and 20 characters long</div>
        </div>
        <br>

        <!-- Enter Password -->
        <div class="form-group">
          <label for="password" class="control-label"><span id="reqInfo">*</span> Password</label>
          <input type="password" name="password" class="form-control" ng-model="register.user.password" ng-minlength="7" id="password"
            required="" placeholder="Enter your password">
          <div ng-messages="registerForm.password.$error" style="color:maroon" role="alert">
            <div ng-message="minlength">Your Password must be at least 7 symbols long</div>
          </div>
        </div>

        <!-- Register button -->
        <div class="form-group">
          <button class="btn btn-primary" type="submit" ng-disabled="!registerForm.name.$valid || !registerForm.age.$valid || !registerForm.email.$valid || !registerForm.username.$valid || !registerForm.password.$valid">Register</button>
        </div>
        <p>Fields with <span id="reqInfo">*</span> must be filled.</p>
  </form>
  </div>

I have been instructed to write in ES6 specifically and I am facing issues with the logic. Please review my code and provide guidance on how to complete it so that I can use it effectively and most importantly, learn from it. Thank you very much in advance!

Answer №1

I recently created a custom directive that can handle various types of validations, both synchronous and asynchronous. It also has the capability to display warnings when needed. Feel free to take a look at it on this link:

`https://plnkr.co/2WQHOo`

If this fits your requirements and you require further details, please don't hesitate to reach out to me. I will do my best to provide answers.

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

Avoid activating automatic save feature in Material UI data grid

After creating a data-grid and attempting to add records, I encountered an issue where pressing the TAB key automatically saved the data when focusing on the save button without manually pressing enter. How can this behavior be prevented so that manual con ...

Adjusting the settimeout delay time during its execution

Is there a way to adjust the setTimeout delay time while it is already running? I tried using debounceTime() as an alternative, but I would like to modify the existing delay time instead of creating a new one. In the code snippet provided, the delay is se ...

The React component designed to consistently render video frames onto a canvas is unfortunately incompatible with iOS devices

I'm facing an issue with my code snippet that is supposed to draw video frames on a canvas every 42 milliseconds. It's working perfectly on all platforms and browsers except for iOS. The video frames seem unable to be drawn on canvas in any brows ...

numerous sections within a solitary webpage

I need to implement multiple tabs on a single page, how do I modify the code to make this possible? Take a look at the codepen for reference. Here is the jquery code I have written so far: var tabs = $(".tabContainer ul li a"); $(".tabConten ...

Insert a JSX element into the body of a webpage using React JSX

Is there a way to dynamically add elements to the end of the body using vanilla JavaScript? const newRecipe = <div id = "container"> <div className="recipe App" id="four" onClick={this.toggleRecipeList.bind(this)}>{this.state.recipeName} < ...

Ways to retrieve information beyond the scope of the 'then' method

One issue I am facing involves a piece of code that is only accessible inside of the 'then' function. I need to access it outside of this block in order to utilize it in other parts of my program. $scope.model = {'first_name':'&ap ...

Passing this as a function parameter in Jquery

HTML <input type="button" id="1" class="add" value="+" title="Add" onclick="set(this);"/> JS function set(obj){ alert(obj.id); } The code snippet provided above seems to have an issue. My Requirement I am looking for a solution that allows ...

parsing and building a sophisticated JSON object

i have a complex array structure as shown below, array=[ { 'mm': '1', exp: 'exp1' }, { 'mm': '2', exp: 'exp2' }, { 'mm': [ '1', '3', '7' ], exp: &ap ...

Determine whether a WebElement contains a particular content within the :after pseudo class

After locating my element in Selenium, I've come across an interesting challenge. IWebElement icon = box.FindElement(By.ClassName("box-icon")); Sometimes, this element (icon) has a content set as follows: &:after { content: $icon-specia ...

In search of an effortless method to effortlessly select numerous elements using a handy bookmarklet

My goal is to develop a bookmarklet that can perform various functions on different webpages with ease. The concept involves placing it in a convenient location, such as the bookmark bar, and executing a "standard function" on a particular page. Instead of ...

Creating dropdown options with JSON and Angular

This dilemma has been causing me no end of distress. I am trying to figure out how to populate options for a select tag from a JSON object using Angular. Here is a snippet of the code: <select id="cargo" ng-model="cargo.values.cargoList"> <op ...

A versatile Material UI paper that adjusts its dimensions dynamically

Utilizing Material-UI's Paper component (https://mui.com/components/paper/), I've encountered a scenario where the content within the Paper element needs to be dynamic. <Paper className="modal" elevation={3}> ...Content </Paper ...

Tree Grid in jqGrid with Offline Data

Accessing the jqGrid documentation for tree grid, I discovered the following information: "At present, jqGrid can only interact with data that is returned from a server. However, there are some tips and resources available that explain how to work w ...

Steps to retrieve values from a grid and execute a sum operation using PROTRACTOR

Embarking on my Protractor and Javascript journey, I am faced with the challenge of writing a test script to retrieve values of various accounts under the header "Revenue" (as shown in the image below). My task involves extracting all number values listed ...

Retrieving the correct selected value from multiple select tables created through a for loop can be achieved using JavaScript or jQuery

Despite searching Google and asking previous questions, I have not found a solution that addresses my specific issue. The common responses only pertain to one select element with multiple options. To further clarify, when I create code for a loop to genera ...

VUE- the GetElementByClassName function is malfunctioning

I attempted to utilize 'getelementbyclassname' within VUE methods. My reason for doing so is that instead of applying information using :style, I would like to adjust the width of the div where I applied my class named 'classon'. I ...

The div on my webpage is not loading its content as expected when using JavaScript

I am having trouble continuously loading the content of a div from another page. Using alert worked fine, but the page data is not loading. JavaScript <script> $(document).ready(function(){ setInterval(function(){$("#loadAvailable").load("update.p ...

Discover how to access the DOM after AngularJS directive rendering is finished

Looking to create a unique scroll pane component using an AngularJS directive? Check out this jsfiddle example for a basic prototype. Here is the concept behind my custom scroll pane: Directice code snippet: myApp.directive('lpScrollPane', ...

Enhancing a node.js application with express()

I am currently utilizing Express MVC with node.js. The primary object I am working with is express(), which is assigned to an alias called app: var express = require('express'); app = express(); Is there a way for me to expand the functionali ...

Conceal the menu when tapping anywhere else

I am working on a project that involves implementing HTML menus that can be shown or hidden when the user interacts with them. Specifically, I want these menus to hide not only when the user clicks on the header again but also when they click outside of th ...