Holiday Notice: Support will be provided on a limited scale from December 24th, 2024, to January 2nd, 2025. Happy holidays and a wonderful New Year!


Topic: MDBDatepicker control value type

Wojciech Marciniak free asked 5 years ago


Expected behavior

Datepicker, as a FormControl should assure proper one-way or two-way binding with model. Angular comes with on-the-fly binding, which is considered one of its major advantages. This needs consistency in the type of data maintained by a control, especially when Typescript is involved. I would expect this beautiful control to accept and expose the same data type all the time, ideally a native TS/JS Date object or UTC timestamp number.

Actual behavior

Datepicker behaves in a weird way. It accepts mostly strings (in the same format as defined in options) on input, but also an object like: {date: IMyDate}. JS Date does not work, neither do other industry standards. Particularly ISO String can't be applied, if not defined as a display format (but who the hell would want to see those strings in their app?).

While reading the value, its type depends on some factors. What I suspect after some testing is that the return value is mostly of the type used on input. If a date is set programatically, it may be usually read as a type conforming to IMyDate interface (but, as I wrote, this type cannot be directly used on input and must be wrapped in object I mentioned).

More problems arise if the control value has been changed in the UI (this is what controls are for, right?). Then the formatted string is returned as a value.

So, the automatic binding, so much comfortable feature of Angular can't be applied to Datepicker, especially when I receive dates as timestamp numbers from back-end and would like to respond in a consistent way. Neither can I use Angular's DatePipe properly if I want to display the property value elsewhere, say, in other format. Sticking to one ore one of two (to be chosen from in options) data types is crucial in my opinion. I'v seen the widget hold its value in all those common standards internally (properties like jsdate, epoc) but they are wrapped.

As a workaround I created two getter/setter functions (see below) I use first - for building the model from the back-end payload, then for posting data back, but this makes the code complex and is not a solution I would consider right in a longer term.

Resources (screenshots, code snippets etc.)

static writeDate(epoch: number | Date): any {
  if (epoch == null) return null;
  let date: Date;
  if (typeof epoch == 'number') {
    date = new Date(epoch);
  } else {
    date = epoch;
  }
  return { date: {
    year: date.getFullYear(),
    month: date.getMonth() + 1,
    day: date.getDate()
  } };
}

static readDate(input: any): number {
  if (input == null) return null;
  if (typeof input == 'string') {
    const ar: string[] = input.split("/");
    if (ar.length > 1) {
      let date: Date = new Date(+ar[2], +ar[1] - 1, +ar[0]);
      return date.getTime();
    } else {
      return null;
    }
  }
  const date: Date = new Date(input.date.year, input.date.month - 1, input.date.day);
  return date.getTime();
}

Arkadiusz Idzikowski staff answered 5 years ago


You are absolutely right, some changes are necessary so that you can easily use our component with Angular form controls. We are already aware of this problem.

If we won't have to introduce any breaking changes, this feature should be available in one of the upcoming releases. Otherwise, we will need to wait for a major update (which we will probably release when Angular 9 will be ready).



Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Answered

Specification of the issue

  • ForumUser: Free
  • Premium support: No
  • Technology: MDB Angular
  • MDB Version: 8.1.1
  • Device: Any
  • Browser: Any
  • OS: Any
  • Provided sample code: Yes
  • Provided link: No