angular-material-components: Angular 11.1.0 NGX-DateTime-Picker 5.0.3 Undefined Stream

Hello. Currently running angular version 11.1.0, Material 11.1.0 and Angular-material-components/datetime-picker as 5.03

The code works as intended. It grabs the values for us and lets us use them. However, upon instantiation the errors are thrown.

It is the same error for every instance:

ERROR TypeError: You provided ‘undefined’ where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

Previous issues have indicated this issue was solved in v4 for angular v10 by updating. This solution no longer works for our situation.

It grabs the values for us and lets us use them. However, upon instantiation the errors are thrown. This is not breaking for us, but it does lead us to wonder if we are doing something wrong:

Our picker is instantiated in the ts file with the following line:

@ViewChild(‘picker’, { static: true }) picker: moment.Moment;

The following is the AMCDateTimePicker.html implementation: AMCDateTimePicker.html

<form
   class="field-row"
   fxLayout="row"
   fxLayoutAlign="space-evenly"
   fxLayoutGap="5%"
   [formGroup]="form"
>
   <mat-form-field>
      <input
         type="text"
         formControlName="{{ controlName }}"
         [min]="minDate"
         [max]="maxDate"
         matInput
         [placeholder]="placeholder"
         [ngxMatDatetimePicker]="picker"
      />
      <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
      <ngx-mat-datetime-picker
         #picker
         [showSpinners]="showSpinners"
         [showSeconds]="showSeconds"
         [stepHour]="stepHour"
         [stepMinute]="stepMinute"
         [stepSecond]="stepSecond"
         [touchUi]="touchUi"
         [enableMeridian]="enableMeridian"
         [disableMinute]="disableMinute"
         [hideTime]="hideTime"
      >
      </ngx-mat-datetime-picker>
   </mat-form-field>
</form>

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 9
  • Comments: 20 (1 by maintainers)

Most upvoted comments

I’ve replace the <mat-datepicker-toggle> with a mat icon button, and it works well:

  <button mat-icon-button matSuffix (click)="picker.open(); $event.stopPropagation();">
    <mat-icon>today</mat-icon>
  </button>

I have to add $event.stopPropagation(); after picker.open();, otherwise the dialog will close immediatly.

Hi all, Sorry for the late reply, a new version 5.1.0 has already been released to fix this bug. This version is compatible with Angular (and Angular Material) 11.1.x or above. Thank you all for your support.

Following the @humblepie’s comment, I made this directive to monkey-patch stateChanges back in:

import { Directive } from "@angular/core";
import { MatDatepickerToggle } from "@angular/material/datepicker";

/**
 * Fixes a bug in ngx-mat-datetime-picker, see:
 * https://github.com/h2qutc/angular-material-components/issues/170#issuecomment-766291615
 */
@Directive({
  selector: '[monkeyPatchNgxMatDatetimePickerIssue170]'
})
export class MonkeyPatchNgxMatDatetimePickerIssue170Directive<T> {
  constructor(toggle: MatDatepickerToggle<T>) {
    const originalOnChanges = toggle.ngOnChanges
    toggle.ngOnChanges = (...args) => {
      const datepicker = toggle.datepicker as any
      if (!datepicker.stateChanges && datepicker._stateChanges) {
        datepicker.stateChanges = datepicker._stateChanges
      }
      originalOnChanges.call(toggle, ...args)
    }
  }
}

Use it like so:

<mat-datepicker-toggle matSuffix monkeyPatchNgxMatDatetimePickerIssue170 [for]='periodTo'></mat-datepicker-toggle>

I have the same issue using the same versions of Angular, Material, and @angular-material-components/datetime-picker.

core.js:6156 ERROR TypeError: You provided ‘undefined’ where a stream was expected. You can provide an Observable, Promise, Array, or Iterable. at subscribeTo (subscribeTo.js:27) at innerSubscribe (innerSubscribe.js:69) at MergeMapSubscriber._innerSub (mergeMap.js:57) at MergeMapSubscriber._tryNext (mergeMap.js:51) at MergeMapSubscriber._next (mergeMap.js:34) at MergeMapSubscriber.next (Subscriber.js:49) at Observable._subscribe (subscribeToArray.js:3) at Observable._trySubscribe (Observable.js:42) at Observable.subscribe (Observable.js:28) at MergeMapOperator.call (mergeMap.js:19) at Observable.subscribe (Observable.js:23) at MatDatepickerToggle._watchStateChanges (datepicker.js:3469) at MatDatepickerToggle.ngAfterContentInit (datepicker.js:3453) at callHook (core.js:2512) at callHooks (core.js:2483)

    _watchStateChanges() {
        const datepickerStateChanged = this.datepicker ? this.datepicker.stateChanges : of();
        const inputStateChanged = this.datepicker && this.datepicker.datepickerInput ?
            this.datepicker.datepickerInput.stateChanges : of();
        const datepickerToggled = this.datepicker ?
            merge(this.datepicker.openedStream, this.datepicker.closedStream) :
            of();
        this._stateChanges.unsubscribe();
        this._stateChanges = merge(this._intl.changes, datepickerStateChanged, inputStateChanged, datepickerToggled).subscribe(() => this._changeDetectorRef.markForCheck());
    }

Looks like error is occurring because Angular Material datepicker now requires property stateChanges. The NgxMatDatetimePicker has a property called _stateChanges on it which if you remove the underscore will probably clear this problem.