1

I am using ng-bootstrap's date/time picker in a form. I have tried to implement this:

https://stackblitz.com/edit/angular-datetimepicker?file=src%2Fapp%2Fapp.component.html

I am getting the following errors in the component.ts file:

Property 'year' does not exist on type 'string | NgbDateStruct'.
Property 'year' does not exist on type 'string'.

Same goes for month and day and also I am getting:

Argument of type 'string | NgbDateStruct' is not assignable to parameter of type 'string'.
Type 'NgbDateStruct' is not assignable to type 'string'.

the components file is:

import { Component, OnInit, Input, forwardRef, ViewChild, AfterViewInit, Injector } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor, NgControl } from '@angular/forms';
import { DatePipe } from '@angular/common';
import { DateTimeModel } from './date-time.model';
import { noop } from 'rxjs';
import { NgbDatepickerConfig, NgbCalendar, NgbDate, NgbPopoverConfig, NgbPopover, NgbDatepicker, NgbDateStruct, NgbTimeStruct} from '@ng-bootstrap/ng-bootstrap';


@Component({
  selector: 'app-date-time-picker',
  templateUrl: './date-time-picker.component.html',
  styleUrls: ['./date-time-picker.component.scss'],
  providers: [
    DatePipe,
    {
        provide: NG_VALUE_ACCESSOR,
        useExisting: forwardRef(() => DateTimePickerComponent),
        multi: true
    }
]
})
export class DateTimePickerComponent implements ControlValueAccessor, OnInit, AfterViewInit {
  @Input()
  dateString: string;

  @Input()
  inputDatetimeFormat = 'yyyy/MM/dd hh:mm:ss';
  @Input()
  hourStep = 1;
  @Input()
  minuteStep = 15;
  @Input()
  secondStep = 30;
  @Input()
  seconds = true;

  @Input()
  disabled = false;

  private showTimePickerToggle = false;

  private datetime: DateTimeModel = new DateTimeModel();
  private firstTimeAssign = true;

  @ViewChild(NgbDatepicker)
  private dp: NgbDatepicker;

  @ViewChild(NgbPopover)
  private popover: NgbPopover;

  private onTouched: () => void = noop;
  private onChange: (_: any) => void = noop;

  private ngControl: NgControl;

  constructor(private config: NgbPopoverConfig, private inj: Injector ) {
      config.autoClose = 'outside';
      config.placement = 'auto';
  }

  ngOnInit(): void {
      this.ngControl = this.inj.get(NgControl);
  }

  ngAfterViewInit(): void {
      this.popover.hidden.subscribe($event => {
          this.showTimePickerToggle = false;
      });
  }

  writeValue(newModel: string) {
      if (newModel) {
          this.datetime = Object.assign(this.datetime, DateTimeModel.fromLocalString(newModel));
          this.dateString = newModel;
          this.setDateStringModel();
      } else {
          this.datetime = new DateTimeModel();
      }
  }

  registerOnChange(fn: any): void {
      this.onChange = fn;
  }

  registerOnTouched(fn: any): void {
      this.onTouched = fn;
  }

  toggleDateTimeState($event) {
      this.showTimePickerToggle = !this.showTimePickerToggle;
      $event.stopPropagation();
  }

  setDisabledState?(isDisabled: boolean): void {
      this.disabled = isDisabled;
  }

  onInputChange($event: any) {
      const value = $event.target.value;
      const dt = DateTimeModel.fromLocalString(value);

      if (dt) {
          this.datetime = dt;
          this.setDateStringModel();
      } else if (value.trim() === '') {
          this.datetime = new DateTimeModel();
          this.dateString = '';
          this.onChange(this.dateString);
      } else {
            this.onChange(value);
      }
  }

  onDateChange($event: string | NgbDateStruct) {        
      if ($event.year){
        $event = `${$event.year}-${$event.month}-${$event.day}`
      }

      const date = DateTimeModel.fromLocalString($event);

      if (!date) {
          this.dateString = this.dateString;
          return;
      }

      if (!this.datetime) {
          this.datetime = date;
      }

      this.datetime.year = date.year;
      this.datetime.month = date.month;
      this.datetime.day = date.day;

      this.dp.navigateTo({ year: this.datetime.year, month: this.datetime.month });
      console.log(this.datetime);
      this.setDateStringModel();
  }

  onTimeChange(event: NgbTimeStruct) {
      this.datetime.hour = event.hour;
      this.datetime.minute = event.minute;
      this.datetime.second = event.second;

      this.setDateStringModel();
  }

  setDateStringModel() {
      this.dateString = this.datetime.toString();

      if (!this.firstTimeAssign) {
          this.onChange(this.dateString);
      } else {
          // Skip very first assignment to null done by Angular
          if (this.dateString !== null) {
              this.firstTimeAssign = false;
          }
      }
  }

  inputBlur($event) {
      this.onTouched();
  }
}

The errors are here:

onDateChange($event: string | NgbDateStruct) {        
      if ($event.year){
        $event = `${$event.year}-${$event.month}-${$event.day}`
      }

      const date = DateTimeModel.fromLocalString($event);

      if (!date) {
          this.dateString = this.dateString;
          return;
      }

Any idea's would be very helpful. Thanks

1 Answer 1

1

It's just a type error. You can try change:

dateString: string;

for

dateString: string | NgbDateStruct;

Sign up to request clarification or add additional context in comments.

2 Comments

I have updated where the errors are. how would I amend there??
Mmm, if you try $event: any? Also try restart (ng serve). It's weird, your code is the same as the example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.