Components: Datepicker throws matDatepickerParse on a empty field not required

Created on 15 Apr 2018  路  6Comments  路  Source: angular/components

#### Bug, feature request, or proposal:
Bug

#### What is the expected behavior?
Focus on a not required field and blur without throwing any errors

#### What is the current behavior?
After focusing and blurring in a not required field without changing its value the datepicker throws the matDatepickerParse error with text ''.
After the field value changes and returns to empty(dirty), the error no longer occurs.

#### What are the steps to reproduce?
In the example provided on the Angular Material website about "Datepicker that uses Moment.js dates" it is possible to reproduce the error
https://stackblitz.com/angular/eqjpjpvgmll?file=app%2Fdatepicker-moment-example.ts

All 6 comments

Maybe I'm missing something, but I wasn't able to get it throw an error on any of the browsers that I tried (Chrome, Firefox, Edge, IE).

I was able to reproduce the error in any browser, follow the link below:

https://media.giphy.com/media/1zKA5y6yPVkjSDtn9o/giphy.gif

But I already identified the error. The error only occurs when starting the FormControl with the value ''. After changing the code to start the control with null, no error was thrown.

import { Moment } from 'moment';
import { CustomValidator } from './../../validators/custom.validator';
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { Task } from '../../model/task.model';
import * as moment from 'moment';
import { DEFAULT_DATE_FORMAT } from '../../app.definitions';
import { TaskService } from '../task.service';
import { MatSnackBar } from '@angular/material';

@Component({
    selector: 'app-task-create',
    templateUrl: './task-create.component.html',
    styleUrls: ['./task-create.component.css']
})
export class TaskCreateComponent implements OnInit {

    taskCreateForm: FormGroup;

    titleControl: FormControl;
    startedAtControl: FormControl;
    plannedForControl: FormControl;
    descriptionControl: FormControl;

    today = new Date();

    constructor(private fb: FormBuilder,
        private router: Router,
        private taskService: TaskService,
        public snackBar: MatSnackBar) { }

    ngOnInit() {
        this.titleControl = this.fb.control(null, [Validators.required]);
        this.startedAtControl = this.fb.control(null);
        this.plannedForControl = this.fb.control(null, [CustomValidator.weekday]);
        this.descriptionControl = this.fb.control(null, [Validators.required]);
        this.taskCreateForm = this.fb.group({
            title: this.titleControl,
            startedAt: this.startedAtControl,
            plannedFor: this.plannedForControl,
            description: this.descriptionControl
        });
    }

    cancel() {
        this.router.navigate(['/task-list']);
    }

    validateAllFormFields(formGroup: FormGroup) {
        if (formGroup.valid) {
            let plannedFor;
            if (this.plannedForControl.value) {
                plannedFor = moment(this.plannedForControl.value).format(DEFAULT_DATE_FORMAT);
            }
            const task = new Task(this.titleControl.value, this.descriptionControl.value, 'P',
                moment(this.startedAtControl.value).format(DEFAULT_DATE_FORMAT), plannedFor);

            this.taskService.create(task)
                .subscribe(taskResult => {
                    this.openSnackBar('Tarefa cadastrada com sucesso');
                    this.router.navigate(['/task-list']);
                });
        } else {
            Object.keys(formGroup.controls).forEach(field => {
                const control = formGroup.get(field);
                if (control instanceof FormControl) {
                    control.markAsTouched({ onlySelf: true });
                } else if (control instanceof FormGroup) {
                    this.validateAllFormFields(control);
                }
            });
        }
    }

    openSnackBar(message: string) {
        this.snackBar.open(message, undefined, {
            duration: 2000,
        });
    }

}

Closing since the issue has been resolved

There is still a scenario where this happens.

  1. Select a date
  2. Add text after the date and blur the field to make it invalid
  3. Clear all text in the field

The field remains in an invalid state despite having no value. My guess is that the value changed from null to '' which would be related to the original issue that @FernandoI7 brought up.

Is there any solution to this? Even if the form is initialized with '' for the FormControl value, when it's cleared out after text is entered, it resets the field to null every time. This is completely blowing up my custom validator.

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings

Related issues

michaelb-01 picture michaelb-01  路  3Comments

jelbourn picture jelbourn  路  3Comments

theunreal picture theunreal  路  3Comments

shlomiassaf picture shlomiassaf  路  3Comments

julianobrasil picture julianobrasil  路  3Comments