Home > Blockchain >  How to get <input type=date> value in TypeScript
How to get <input type=date> value in TypeScript

Time:12-07

I'm making a survey website and what I'm trying to do is get two dates from the user: start date and end date, and make the survey available between these days (I'll disable the take survey button after the end date). Before even getting to coding this logic, I can't take the user's input and display it in the console log. Here is what I have so far:

HTML:

<input formControlName="startDate" id="startDate" type="date"/>

TypeScript:

const startDate = document.getElementById('startDate') as HTMLInputElement | null;

console.log(startDate?.value);

And the console.log tells me it's undefined. Any ideas on how to fix this?

document.querySelector('input').addEventListener('change', () => {
  const startDate = document.getElementById('startDate')

  console.log(startDate.value);
})
<input formControlName="startDate" id="startDate" type="date" />

CodePudding user response:

I don't really know why you are trying to use vanilla Javascript in an Angular project which uses Typescript, is not ideal, is not the Angular way.

Given your code example, you are using ReactiveForms, your input element has a formControlName which means, somewhere in the component's logic, you have the whole form created as a Javascript object, something like the following:

...
  myForm!: FormGroup;  

  constructor(private fb: FormBuilder) {}

  ngOnInit(): void {
    this.myForm = this.fb.group({
       startDate: ['', Validators.required]
    });
  }

If you simply want the value of the startDate control, then use the form object accessing the specific control, like this:

getDate(): Date | undefined {
  return this.myForm.get('startDate')?.value; // it can be undefined
}

If you want to listen the input change everytime the user changes the value, then use valueChanges like the following:

ngOnInit(): void {
  this.myForm.get('startDate').valueChanges.subscribe((theDate) => console.log(theDate));
}

Let's say you are not using ReactiveForms, and you want to select this input element, you could do it using a local reference onto the input element, and then access it in your code using ViewChild, like the following:

<input type="text" #myName/>
...
 @ViewChild('myName') myName!: ElementRef;

 getName(): string {
   return this.myName.nativeElement.value;
 }

I highly suggest you to read the official docs, if you don't know how to solve an specific scenario in an Angular project.

CodePudding user response:

You can use a type guard function to check whether the selected element is actually an input element before binding the callback function to its change event:

TS Playground

function isInputElement (
  value: Element | null | undefined,
): value is HTMLInputElement {
  return value?.tagName === 'INPUT';
}

const startDateInput = document.getElementById('startDate');

if (isInputElement(startDateInput)) {
  // If the condition evaluates to true,
  // then the compiler is certain that it's an <input>:
  startDateInput.addEventListener('change', () => {
    console.log(startDateInput.value);
                            //^? (property) HTMLInputElement.value: string
  });
}
else {
  // The element either didn't exist
  // or it wasn't an <input>
}

Compiled JS from the TS playground:

"use strict";
function isInputElement(value) {
    return value?.tagName === 'INPUT';
}
const startDateInput = document.getElementById('startDate');
if (isInputElement(startDateInput)) {
    startDateInput.addEventListener('change', () => {
        console.log(startDateInput.value);
    });
}
else {
}
<input formControlName="startDate" id="startDate" type="date" />

  • Related