dynamically set the date value in matdatepicker field affect the another matDatePicker field Date in Reactive Form

2.7k views Asked by At

I have two matDatePicker control (statement date and start date) in my reative form I have dynamically set the value of start date field based on statement date field value and number of month.

<div [formGroup]="parameters">
<div class="mat-field">
    <mat-form-field color="primary">
        <mat-label>Statement Date</mat-label>
        <input id="statementDate" matInput [matDatepicker]="statementDatePicker"  formControlName="statementDate"  (dateChange)="datechanged()" >
        <mat-datepicker-toggle matSuffix [for]="statementDatePicker"></mat-datepicker-toggle>
        <mat-datepicker #statementDatePicker></mat-datepicker>
    </mat-form-field>
</div>
<div class="mat-field">
    <mat-form-field>
        <mat-label>Start Date</mat-label>
        <input id="startDate" matInput [matDatepicker]="startDatepicker" formControlName="startDate" readonly [disabled]="parameters.value.period!='other'">
        <mat-datepicker-toggle matSuffix [for]="startDatepicker"></mat-datepicker-toggle>
        <mat-datepicker #startDatepicker></mat-datepicker>
    </mat-form-field>
</div>
<div class="mat-field">

    <mat-form-field>
        <mat-label>Period</mat-label>
        <mat-select id="period" matInput formControlName="period" (selectionChange)="datechanged()">
            <mat-option value="12">12 Months</mat-option>
            <mat-option value="11">11 Months</mat-option>
            <mat-option value="10">10 Months</mat-option>
            <mat-option value="9">9 Months</mat-option>
            <mat-option value="8">8 Months</mat-option>
            <mat-option value="7">7 Months</mat-option>
            <mat-option value="6">6 Months</mat-option>
            <mat-option value="5">5 Months</mat-option>
            <mat-option value="4">4 Months</mat-option>
            <mat-option value="3">3 Months</mat-option>
            <mat-option value="2">2 Months</mat-option>
            <mat-option value="1">1 Month</mat-option>
            <mat-option value="other">other</mat-option>
        </mat-select>
    </mat-form-field>
</div>

ts file

 export class DatepickerMinMaxExample {
 parameters: FormGroup

  constructor(
    private fb: FormBuilder
  ) { }

  ngOnInit() {
   this.parameters = new FormGroup({
      'statementDate': new FormControl(null, Validators.required),
      'startDate': new FormControl(null, Validators.required),
      'period': new FormControl(null, Validators.required),
  });

  }
    
 public datechanged(){
    if(this.parameters.controls['statementDate'].value!=null&& this.parameters.controls['period'].value!=null&& this.parameters.controls['period'].value!='other'){
      let stmtDate=this.parameters.controls['statementDate'].value;
      let send_date=this.parameters.controls['statementDate'].value;
      console.log('statement date: '+ this.parameters.controls['statementDate'].value)
      let period=parseInt(this.parameters.controls['period'].value)
      let formattedDate : any;
   
      send_date.setMonth(send_date.getMonth()-period);
      send_date.setDate(send_date.getDate()+1);
      formattedDate=send_date.toISOString().slice(0,10);
      console.log('format date: '+ formattedDate)
      console.log('stment date after format date: '+ stmtDate)
      this.parameters.controls['startDate'].setValue(new Date(formattedDate))
    }

}
}

dynamically updating the start date value affect the statement date matDatePicker and value as well. enter image description here

enter image description here

Stackblitz

Please help me to resolve this issue.

Thanks in advance.

2

There are 2 answers

0
Muthukani K On BEST ANSWER
public datechanged(){
    if(this.parameters.controls['statementDate'].value!=null&& this.parameters.controls['period'].value!=null&& this.parameters.controls['period'].value!='other'){
      this.parameters.controls['startDate'].setValue(new Date(this.parameters.controls['statementDate'].value))
      let startDate=this.parameters.controls['startDate'].value
      let period=parseInt(this.parameters.controls['period'].value)
      let formattedDate : any;
   
      startDate.setMonth(startDate.getMonth()-period);
      startDate.setDate(startDate.getDate()+1);
      formattedDate=startDate.toISOString().slice(0,10);
      this.parameters.controls['startDate'].setValue(new Date(formattedDate))
    }

}
0
Tarun Sharma On

It looks like stmtDate and send_date in your datechanged() function are reference types, referring to this.parameters.controls['statementDate'].value. Consequently changing either of those two variables changes the date in your statementDatePicker.

Doing a deep copy of those two fields, using cloneDeep from Lodash gets it to work.

      const _ = require("lodash");

      let stmtDate = _.cloneDeep(
        this.parameters.controls["statementDate"].value
      );
      let send_date = _.cloneDeep(
        this.parameters.controls["statementDate"].value
      );

(Note: I opted for Lodash over traditional methods of deep copy such as the spread operator, Object.assign() and JSON.parse(JSON.stringify(value)) since they don't copy functions, while cloneDeep from Lodash does, and in your case your send_date variable is using functions such as setMonth(), etc.)

I forked your Stackblitz and made a working example