Error message: Custom binding handler failed: 'Flatpickr' is not a valid constructor

Trying my hand at creating a custom binding handler in knockout for Flatpickr has hit a snag. Upon attempting to use it, an error is thrown:

Uncaught TypeError: Unable to process binding "datetimepicker: function (){return startDate }"
Message: Flatpickr is not a constructor
    at init (knockout.bindings.ts:16)

The custom binding handler in question looks like this:

import ko from 'knockout';
import $ from 'jquery';
import * as Flatpickr from 'flatpickr';

let bindingHandlers: any = ko.bindingHandlers;

bindingHandlers.datetimepicker = {
    init: function (element: any, valueAccessor: any, allBindingsAccessor: any) {
        var options = $.extend({
            dateFormat: 'DD-MM-YYYY',
            enableTime: true
        }, allBindingsAccessor().datetimepickerOptions),
            $el = $(element),
            picker = new Flatpickr(element, options),
            observable = valueAccessor();

        //handle the field changing by registering datepicker's changeDate event
        ko.utils.registerEventHandler(element, "change", function () {
            observable(picker.parseDate(($<any>$el).val(), 'DD-MM-YYYY'));
        });

        //handle disposal (if KO removes by the template binding)
        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
            ($<any>$el).flatpickr("destroy");
        });

        observable.subscribe(function (newVal: any) {
            ($<any>$el).val(picker.formatDate(options.dateFormat, newVal));
        });

        picker.setDate(ko.unwrap(observable));
    }
};

The associated Typescript definition file contains:

// Type definitions for flatpickr 3.0
// Project: https://github.com/chmln/flatpickr
// Definitions by: James Birtles <https://github.com/UnwrittenFun>
//                 Rowell Heria <https://github.com/rowellx68>
//                 Michael Wagner <https://github.com/wagich>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped

(...)

export = Flatpickr;

View snippet using the custom binding:

<!-- ko with: assignment -->
<form>
    <div class="form-group">
        <label for="startDate" class="control-label">Start date</label>
        <input data-bind="attr: { id: 'startDate' + $parent.selector() }, datetimepicker: startDate, datetimepickerOptions:{ enableTime: false }" type="text" class="form-control" />
    </div>
    <div class="form-group">
        <label for="endDate" class="control-label">End date</label>
        <input data-bind="attr: { id: 'endDate' + $parent.selector() }, datetimepicker: startDate, datetimepickerOptions:{ enableTime: false }" type="text" class="form-control" />
    </div>
</form>
<!-- /ko -->

Model setup for the page:

class AssignmentModel {
    (...)

}

class AssignmentGroupModel {
    (...)    
}


A puzzling issue arises when indicating that Flatpickr is not recognized as a constructor. Despite Visual Studio displaying the constructor correctly upon hover.

Answer №1

The issue arose from how I was importing the Flatpickr library. I made adjustments to my import statement as shown below:

import Flatpickr from 'flatpickr';

With this change, everything is functioning properly now. I also updated my custom binding handler like so:

ko.bindingHandlers.datetimepicker = {
    init: function (element: any, valueAccessor: any, allBindingsAccessor: any) {
        var options = {
            ...allBindingsAccessor().flatpickrOptions,
            dateFormat: 'd-m-Y',
            enableTime: false
        }
        let picker = new Flatpickr(element, options);
        let $el = $(element);
        $el.data('dtp', picker);

        ko.utils.registerEventHandler(element, "change", function () {
            let momentValue = moment(element.value, 'DD-MM-YYYY');
            valueAccessor()(momentValue);
        });

        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
            (<any>element).flatpickr("destroy");
        });
    },
    update: function (element: any, valueAccessor: any) {
        let picker = $(element).data('dtp');
        let value = ko.unwrap(valueAccessor());
        picker.setDate(value.format('DD-MM-YYYY'));
    }
};

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Upon executing the `npm start` command, the application experiences a crash

When I tried following the steps of the Angular quickstart guide, I encountered some errors after running "npm start". Here are the errors displayed: node_modules/@angular/common/src/directives/ng_class.d.ts(46,34): error TS2304: Cannot find name 'Se ...

What is the reason for a class's attributes being considered undefined even after they have been previously set?

Within my code, there is a class called WorkspaceDatabase that stems from the Dynamic Tree Example. I have incorporated some debugging information to gain a clearer understanding of the issue at hand. The Issue: Upon entering the complete() function, an ...

Typescript: Subscribed information mysteriously disappeared

[ Voting to avoid putting everything inside ngOnit because I need to reuse the API response and model array in multiple functions. Need a way to reuse without cluttering up ngOnInit. I could simply call subscribe repeatedly in each function to solve the p ...

Transfer the data stored in the ts variable to a JavaScript file

Is it possible to utilize the content of a ts variable in a js file? I find myself at a loss realizing I am unsure of how to achieve this. Please provide any simple implementation suggestions if available. In my ts file, there is a printedOption that I w ...

Unable to utilize Google Storage within a TypeScript environment

I'm encountering an issue while attempting to integrate the Google Storage node.js module into my Firebase Cloud functions using TypeScript. //myfile.ts import { Storage } from '@google-cloud/storage'; const storageInstance = new Storage({ ...

Generating PDF files from HTML using Angular 6

I am trying to export a PDF from an HTML in Angular 6 using the jspdf library. However, I am facing limitations when it comes to styling such as color and background color. Is there any other free library besides jspdf that I can use to achieve this? Feel ...

Ensuring Consistency of Values Between Child and Parent Components

Is there a way to ensure that the value of submitted in the child component always matches the value of submitted in the parent component? Appreciate any help! @Component({ selector: 'child-cmp', template: ` child:{{submitted}} ...

Is there a way to omit type arguments in TypeScript when they are not needed?

Here is a function I am currently working with: function progress<T>(data: JsonApiQueryData<T>): number { const { links, meta } = data.getMeta(); if (!links.next) { return 1; } const url = new URL(links.next); return parseInt(url ...

Incorporate the {{ }} syntax to implement the Function

Can a function, such as toLocaleLowerCase(), be used inside {{ }}? If not, is there an alternative method for achieving this? <div *ngFor="let item of elements| keyvalue :originalOrder" class="row mt-3"> <label class=" ...

Is there a way to expand the return type of a parent class's methods using an object

Currently, I am enhancing a class by adding a serialize method. My goal is for this new method to perform the same functionality as its parent class but with some additional keys added. export declare class Parent { serialize(): { x: number; ...

Discovering the number of items that have been filtered in isotope-layout using React and Typescript

Currently, I am utilizing the isotope-layout library within a React (Typescript) project. Although I have successfully implemented filtering on my page, I am unsure of how to retrieve the count of the filtered items. Upon loading the page, Isotope is init ...

Error in Firebase Functions: Promises must be properly managed

Currently, I am in the process of creating a Firebase function using TypeScript to deliver push notifications to multiple users. However, whenever I execute the command firebase deploy --only functions, TSLint flags an error stating "Promises must be han ...

Issues with TypeScript "Compile on save" functionality in Visual Studio 2015

The feature of "Compile on save" is not functioning properly for me since I upgraded to Visual Studio 2015. Even though the status bar at the bottom of the IDE shows Output(s) generated successfully after I make changes to a .ts file and save it, the resul ...

Why does the error message "DeprecationWarning: 'originalKeywordKind' deprecated" keep popping up while I'm trying to compile my project?

Upon completing the compilation of my project, I encountered the error message provided below. What does this signify and what steps can I take to resolve it? - info Linting and checking validity of types DeprecationWarning: 'originalKeywordKind' ...

When I attempt to add a todo item by clicking, the Url value is displayed as "undefined"

I am facing an issue with my household app where, upon clicking the button to navigate to the addtodo page, the URL specific to the user's house is getting lost. This results in the todolist being stored as undefined on Firebase instead of under the c ...

Creating a seamless integration between Angular 2's auth guard and observables to enhance application security

I'm having trouble setting up an auth guard for one of my routes because I am unsure how to implement it with an observable. I am using ngrx/store to store my token. In the guard, I retrieve it using this.store.select('auth'), which returns ...

Is there a way to enable code completion for Firebase on VS Code?

After successfully setting up Typescript for code completion following the guidelines provided in this resource, I now want to enable code completion for Firebase in VS Code. However, I am unsure of the steps to achieve this. How can I activate code compl ...

Guide on incorporating external .d.ts files for a module

I'm currently delving into the process of utilizing an external .d.ts file that is not included in the module. My intention is to make use of xlsx, which lacks its own type definitions, and instead incorporate them from the package @types/xlsx. Afte ...

The error message "Uncaught ReferenceError: exports is not defined and require" indicates that

I am currently developing an app using angularjs and typescript, but I've encountered a persistent error that has me stumped. Below is the snippet of my code: export var NgApp = new application.Startup(); ///<reference path="../../../../../typin ...

The error `TypeError: Unable to access properties of an undefined value (reading 'authService')` occurred

I'm attempting to check if a user is already stored in local storage before fetching it from the database: async getQuestion(id: string): Promise<Question> { let res: Question await this.db.collection("questions").doc(i ...