Angular model-based forms encounter an issue with converting null to an object during asynchronous validation

In my Angular app, I'm working on implementing async validation for a model-based form. I've simplified the form by removing other fields for clarity, but there are additional fields in the actual form. The goal is to check if a username is unique by calling a service asynchronously. The service is functioning correctly and the results are displayed in the console as expected.

buildForm(): void {
    this.registerForm = this.fb.group({
      'username': 
        [this.user.username, [Validators.required, Validators.minLength(4)],
            [this.validateUsernameUnique.bind(this)]]
    });
    this.registerForm.valueChanges
      .subscribe(data => this.onValueChanged(data));
    this.onValueChanged();  // set validation messages now
  }

The validateUsernameUnique() method should check if a username already exists by making a remote call to a service and return true or false. The delay in validation should occur until the value is at least 4 characters long to allow the minLength(4) validation message to show up as expected.

The validation messages are defined as follows:

formErrors = {
    'username': ''
};
validationMessages = {
    'username': {
      'required': 'username is required',
      'minlength': 'username must be at least 4 characters long',
      'nameTaken': 'username already exists'
    }
};

Although the minLength() validation works as expected initially, once the input reaches 4 characters, an exception is thrown in the console:

TypeError: can't convert null to object
Stack trace:
UserRegisterComponent.prototype.onValueChanged@webpack-internal:///./src/app/user/user-register/user-register.component.ts:111:39
UserRegisterComponent.prototype.buildForm/<@webpack-internal:///./src/app/user/user-register/user-register.component.ts:63:49

After the error occurs, no validation messages are displayed, and the minLength validation does not work either.

The stack trace points to onValueChanged():111, and the method is defined as follows:

onValueChanged(data?: any) {
   if (!this.registerForm) {
     return;
   }
   const form = this.registerForm;
   for (const field of  Object.keys(this.formErrors)) {
     this.formErrors[field] = '';
     const control = form.get(field);
     if (control && control.dirty && !control.valid) {
       const messages = this.validationMessages[field];
       for (const key of Object.keys(control.errors)) {
         this.formErrors[field] += messages[key] + ' ';
       }
     }
   }
 }
  • How can I make synchronous and async validations work together seamlessly? I followed the approach of implementing an async validation method in the same component as the form, as suggested by Stack Overflow.

  • How can I display the nameTaken error message on the form? Is resolve({nameTaken: true}); the correct way to handle this in the validation Promise?

Any insights or suggestions on how to debug the current behavior would be greatly appreciated.

Answer №1

There seems to be an error in the function validateUsernameUnique(). The line

return this.userService.doesUsernameExist(control.value).then()...
causes the function to return before the request is complete.

Try removing the return before

this.userService.doesUsernameExist(...)
.

If the error persists, it may be due to attempting to call Object.keys() on a null value. Verify the value of control.errors before using Object.keys(control.errors).

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

Encountering difficulty when integrating external JavaScript libraries into Angular 5

Currently, I am integrating the community js library version of jsplumb with my Angular 5 application (Angular CLI: 1.6.1). Upon my initial build without any modifications to tsconfig.json, I encountered the following error: ERROR in src/app/jsplumb/jspl ...

Unleashing the power of Typescript enums in conjunction with external modules through browserify

Previously, I utilized TypeScript internal modules and included numerous script tags to initialize my app. Now, I am in the process of transitioning the project to utilize external modules (using browserify), but I have hit a roadblock when it comes to con ...

Angular 10 does not fulfill promises as expected

In the Angular 10 project I'm working on, I encountered an issue while trying to call an API request asynchronously using promises. The code I wrote didn't seem to execute the API call as expected and kept exiting at the first line without progre ...

Having trouble with 'npm <script-command>' not working? Try changing it to 'npm run-script <script-command>' instead

Currently, I am configuring a node js backend to operate on TS for the first time within a mono-repo that has a specific folder structure. You can view the structure here. The package.json file is located in the main directory as shown below: "scr ...

Angular 6: Sending Back HTTP Headers

I have been working on a small Angular Application for educational purposes, where I am utilizing a .net core WebApi to interact with data. One question that has come up involves the consistent use of headers in all Post and Put requests: const headers = ...

Connecting Angular TextArea functionality to the Ctrl-Enter keyboard shortcut

Recently, I've been working on creating a custom functionality for the <textarea> element. My goal is to have the enter key trigger a specific function, while using ctrl+enter will add a new line in the textarea. I've tried looking through ...

Refresh the page using a promise in Angular after a delay of 3 seconds

Currently, I am working on enhancing the functionality of the login page. In case a user enters an incorrect login and password combination, my goal is to have the page automatically reload after 3 seconds. Despite my best efforts, I have encountered chall ...

SonarQube alerting you to "Eliminate this unnecessary casting"

Can someone help me understand why SonarQube is flagging this error and suggest a resolution? The unnecessary cast should be removed. Promise.all([ this.customerViewCmr4tProvider.getData(activeNumber), this.customerBillManagementProvider.getData(ind ...

When combining Angular with Workbox, you may encounter a ChunkLoadError stating that the loading of a specific chunk was refused to execute due to mismatch

When I added Workbox to Angular for the first production deployment, everything worked smoothly. However, after updating a module, rebuilding Angular, and injecting Workbox again, I encountered an issue. Upon visiting the site, I noticed that the service w ...

What is the correct method for caching fonts within an Angular application?

In the process of developing a web application similar to photoshop-minis using Angular, one key aspect I am focusing on is reducing load times. Particularly when it comes to fonts, as not all necessary fonts are available through Google Fonts. Instead of ...

Are items placed into an array passed by reference or by value?

When working with custom Objects in an Angular context, I define two objects "a" and "b" using an interface. These are created as class attributes along with an empty array of these objects. public a: CustomObj; public b: CustomObj; public array: ...

Unable to determine the data type of the JSON object during the

I'm having trouble reading an Object type of json... Here is the json I'm working with: body: { "111": { "name": "name1", "status": 10000 }, "222": { "name": "name2", "status": 20000 }, "333": ...

What is the best way to send various parameters to a component using [routerLink] or router.navigate?

My app-routing.module.ts is configured as shown below: const routes: Routes = [ { path: "branches/:branch", component: BranchesComponent }, // ... ]; In addition, in my app.component.html, I have the following code: <li> ...

Having trouble retrieving data from Angular's InMemoryDbService

After completing the Angular 4 Heroes tutorial, I felt prepared to create my own project. However, when attempting to use an in-memory database to retrieve data and display it in a list, I encountered some difficulties. The list was not showing up as expec ...

Declare a variable that can be accessed by all components

I am working on creating variables that can be accessed across all components within my Angular application. By creating a service that facilitates user connection, I aim to capture user information during the login process and store them in variables tha ...

Issue with displaying labels in ChartJS plugin on Ionic 3 platform

Currently, I am using Ionic 3 and have implemented a bar chart in my project. However, I am facing an issue where the data labels are not being displayed next to the bars on the chart. This is similar to the problem discussed in this question how to displa ...

Guide on incorporating finos/perspective into an Angular 8 project using https://perspective.finos.org/

I am looking for guidance on incorporating Finos/Perspective Datagrid into my Angular 8 application. I need to input data in JSON format and have it output as a Datagrid. Any sample code or examples would be greatly appreciated. You can find the GitHub re ...

Validation of the JSON schema has encountered an error. The value in the array does not meet the requirement as it should be either a null or an object. This issue has been identified in

Summary: I encountered an error message regarding JSON schema validation when working with a custom HTTPS Sample Request payload that includes arrays. The error specifically states that the array requires an object or null value, but found an array instea ...

Integrating Octokit middleware in Next.js for enhanced functionality

Currently, I am in the process of honing my skills by creating a GitHub app. In Octokit, there is a feature called createNodeMiddleware that caught my attention. However, integrating it with next.js seems to pose some challenges. My main issue right now re ...

Troubleshooting Angular2: SVG Disappearing Upon Page Reload with PathLocationStrategy

I encountered a strange problem with SVG while using Angular2's PathLocationStrategy. The SVG code in my HTML template looks like this: <svg class="bell__icon" viewBox="0 0 32 32"> <use xlink:href="#icon-notificationsmall"></use&g ...