Search code examples
htmlangulartypescriptangular-forms

Angular form inputs not matching the data type as per the interface declared when being assigned


Why is the form builder values not matching the type as per declared in the interface? How do I make sure that my numbers input do not get converted to string in the formGroup, given that I have strictly set that user can only input numbers.

I have a sample form here:

<form [formGroup]="exampleForm" (ngSubmit)="onSubmit()">
  <div class="form-group">
    <label>Name: </label>
      <input class="form-control" formControlName="name">

    <br><label>Age: </label>
      <input class="form-control" formControlName="age">

    <br><button>Submit</button>
  </div>
</form>

and an interface that has the exact same attributes as the form inputs:

export interface SampleInterface {
  name: string;
  age: number;
}

upon submission of the form, I assign the form values to the interface object instance. I thought that this would then automatically match the age to number type as per the interface. However, this is not the case as I tried to print the interface object instance and I am seeing it being taken as a string.

In my component.ts:

  onSubmit(){
    let submittedData = this.exampleForm.value;
    this.sampleObject = submittedData;
    console.log(this.sampleObject);
  }

This is being printed in the console:

>{name: "Mike", age: "20"}
age: "20"
name: "Mike"
__proto__: Object

You may find the demo HERE.


Solution

  • As I put in my comment, interfaces do not deal with type conversion, and the input field is using strings as it's default behaviour.

    Add the type attribute to your age and set to number.

    <form [formGroup]="exampleForm" (ngSubmit)="onSubmit()">
      <div class="form-group">
        <label>Name: </label>
          <input class="form-control" formControlName="name">
    
        <br><label>Age: </label>
          <input class="form-control" type="number" formControlName="age">
    
        <br><button>Submit</button>
      </div>
    </form>
    

    Updated stackblitz: https://stackblitz.com/edit/angular-jjrkaj

    -Update-

    To remove the up and down from number inputs, in your global styles you can apply the following style.

    styles.css

    input[type=number]::-webkit-inner-spin-button, 
    input[type=number]::-webkit-outer-spin-button { 
      -webkit-appearance: none; 
      margin: 0; 
    }
    

    Or you could create a directive, to sit on the number, which handles parsing, but that might be overkill.