ng2-datepicker icon indicating copy to clipboard operation
ng2-datepicker copied to clipboard

Is there a way to update the model of the datepicker from an asynchronous call?

Open snstarosciak opened this issue 7 years ago • 12 comments

Hey there,

When I run an asynchronous call, I'd like to be able to update the value of the datepicker, as I use it as part of my form for editing something. Is there an option for this?

snstarosciak avatar Mar 23 '17 02:03 snstarosciak

yes, check https://github.com/jkuri/ng2-datepicker/blob/master/src/ng2-datepicker/ng2-datepicker.component.ts#L147. Something like:

import { Component, EventEmitter } from '@angular/core';
import { DateModel } from 'ng2-datepicker';
...
@Component({
  selector: 'my-component',
  template: `<ng2-datepicker [inputEvents]="datepickerInputEvents"></ng2-datepicker>"`
})
export class MyComponent {
  datepickerInputEvents: EventEmitter<{ type: string, data: string | DateModel }>;

  constructor() {
    this.datepickerInputEvents = new EventEmitter<{ type: string, data: string | DateModel }>();
  }

  doSomething(): void {
    myAsyncCall().then(() => {
      let data: DateModel = new DateModel({ day: 23, month: 2, year: 2017 });
      this.datepickerInputEvents.emit({ type: 'setDate', data: data });
    });
  }
}

hope this helps. cheers!

jkuri avatar Mar 23 '17 06:03 jkuri

hey jkuri, thanks so much for the quick response!

I'm running into one issue though. I'm following your code, and your line:

let data: DateModel = new DateModel({ day: 23, month: 2, year: 2017 });

This actually gives me a typescript error of:

Argument of type '{ day: number; month: number; year: number; }' is not assignable to parameter of type 'IDateModel'. Types of property 'day' are incompatible. Type 'number' is not assignable to type 'string'.)

Do you have any idea what's causing this?

snstarosciak avatar Mar 23 '17 13:03 snstarosciak

just try adding quotes around values

jkuri avatar Mar 23 '17 13:03 jkuri

Hmmm well to make those typescript errors go away, I ended up changing the object like this:

let data: DateModel = new DateModel({ day: "23", month: "2", year: "2017", formatted: "02/23/2017", momentObj: moment(requestData.issuedDate) });

However, now my line of code right under it is causing an error Input data must be an instance of Date!

Here is the offending code:

this.issuedDateInputEvents.emit({ type: 'setDate', data: data });

I should also note that in my component I have a public variable:

public issuedDateInputEvents: EventEmitter<{ type: string, data: string | DateModel }>;

And in my constructor, I have it being set:

this.issuedDateInputEvents = new EventEmitter<{ type: string, data: string | DateModel }>();

Any thoughts?

snstarosciak avatar Mar 23 '17 13:03 snstarosciak

I believe you found a bug, will take a look but cannot before the weekend. If you'd like you can create a PR with solution and I'll accept it.

jkuri avatar Mar 23 '17 14:03 jkuri

Yeah I can do that :) What's interesting is that if I replace the offending line with:

this.issuedDateInputEvents.emit({ type: 'setDate', data: new Date(requestData.issued_date) });

It will populate correctly. On the other hand, if I have my options with an initialDate parameter, I'll get inconsistent input population, so for example, when I have options set like this:

public options: DatePickerOptions = {
    initialDate: new Date(),
    format: "MM/DD/YYYY"
  };

There seems to be a competition between setting the initialDate, as well as setting it via the EventEmitter so sometimes it'll be today's date and other times it'll be the date set from the async call. If I remove initialDate: new Date() from the options object, my async call will update the input properly every single time, but when I have an instance where there is no async call, the input field is completely blank.

Gotta love Angular right? :P

snstarosciak avatar Mar 23 '17 14:03 snstarosciak

its not Angular fault but problem with this module. good you got it working.

jkuri avatar Mar 23 '17 14:03 jkuri

Yeah, it took a bit of finesse, but here's ultimately what my code had to look like in order to get both cases of an async/non-async version of the datepicker to update correctly:

public issuedDateInputEvents: EventEmitter<{ type: string, data: any  }>;

constructor(
  ) {
      this.issuedDateInputEvents = new EventEmitter<{ type: string, data:  DateModel }>();
   }

ngAfterViewInit() {
    if(!this.isEditing) {
      this.issuedDateInputEvents.emit({ type: 'setDate', data: new Date() });
    }
  }

doSomething(): void {
    myAsyncCall().then((requestData) => {
      this.issuedDateInputEvents.emit({ type: 'setDate', data: new Date(requestData.issued_date) });
    });
  }

My use case works for now, but there were a few work-arounds. I still think it's okay, because this is a nice Datepicker :)

snstarosciak avatar Mar 23 '17 14:03 snstarosciak

@snstarosciak @jkuri

I am getting this error --> ErrorInput data must be an instance of Date!

HTML:

<ng2-datepicker #startDate [(ngModel)]="date" [options]="options" (outputEvents)="handleDateChange($event,date)" [inputEvents]="issuedDateInputEvents">

constructor:

this.issuedDateInputEvents = new EventEmitter<{ type: string, data: string | DateModel }>();

.ts

dateString = '2015-05-05';
let data: DateModel = new DateModel({
day: "23", month: "2", year: "2017", formatted:
"02/23/2017", momentObj: moment(dateString, 'YYYY-MMM-DD')
});

this.issuedDateInputEvents.emit({ type: 'setDate', data: data });

rrohitesh avatar May 04 '17 09:05 rrohitesh

@jkuri Hi there! Look like that trick doesn't work any more: Can't bind to 'inputEvents' since it isn't a known property of 'ng-datepicker'. Is there any other way to update the value?

kostyanet avatar Sep 17 '18 09:09 kostyanet

@kostyanet [inputEvents] are deprecated and not used anymore. Check here. You should use

<ng-datepicker [isOpened]="calendarOpened"></ng-datepicker>

and

export class YourComponent {
  calendarOpened: boolean;

  toggleCalendar(): void {
    this.calendarOpened = !this.calendarOpened;
  }
}

something like that, hope you got an idea.

jkuri avatar Sep 17 '18 09:09 jkuri

@jkuri Thanks for your quick reply, it works!

kostyanet avatar Sep 17 '18 11:09 kostyanet