The ko.mapping function is throwing an error because it cannot access the property 'fromJS' which is undefined

I am currently exploring typescript and attempting to integrate knockout.mapping into my project, but I'm facing some challenges.

Despite installing the necessary libraries for knockout and knockout.mapping, along with their respective "@types" declarations, I still can't seem to get it to function properly.

Within my laravel project, I am utilizing typescript and leveraging laravel mix to compile the JavaScript files.

Below is a snippet of my code:

///<reference path="../../../../node_modules/@types/jquery/index.d.ts"/>
///<reference path="../../../../node_modules/@types/knockout/index.d.ts"/>
///<reference path="../../../../node_modules/@types/knockout.mapping/index.d.ts"/>

import * as ko from "knockout";
import * as $ from "jquery";

$(function(){
    // Simple test to verify if ko.mapping exists on the ko object. Unfortunately, it does not appear to be available.
    console.log("Message from jQuery Done", (ko));
});

class MyModel {
    _data: any;
    constructor(the_data: object)
    {
        let self = this;
        let example_observable = ko.observable(); // This works fine

        ko.mapping.fromJS(the_data, self._data); // Throws an error - Cannot read property 'fromJS' of undefined
    }
}

let myModel = new MyModel({"x": "y"});
ko.applyBindings(myModel);

My package.json file lists the dependencies for knockout and knockout.mapping.

    "@types/jquery": "^3.3.6",
    "@types/knockout": "^3.4.58",
    "@types/knockout.mapping": "^2.0.33",
    "ajv": "^6.5.2",
    "knockout": "^3.4.2",
    "knockout.mapping": "^2.4.3",

I am struggling to comprehend what I might be doing incorrectly.

Any assistance would be greatly appreciated.

Thank you in advance.

Answer №1

It seems like the Knockout mapping script may not be loaded in your browser correctly. This script is separate from the core Knockout library.

If you haven't already, you can download it from here: https://www.npmjs.com/package/knockout-mapping

Make sure to include it in your page or bundle. Just referencing types does not automatically provide access to the mapping library.

To quickly check if it's working, try adding a script tag that references the mapping library from a CDN:

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>

One more thing to note - there's no need for the following line of code:

let self = this;

In TypeScript, the scoping of "this" is handled better, so you can directly refer to "this".

Answer №2

This solution worked perfectly for me. It may not be the most elegant, but it gets the job done.

I encountered an issue with "laravel mix".

To resolve this, I needed to make the following addition in my webpackconfig:

mix.webpackConfig({   
    //...
    externals: { // I assumed any "global" libraries would go here.
        'knockout': 'ko'
    }
    //...
});

In my HTML file, I had to include the following:

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>

And just like that, problem solved!

I attempted to use mix.autoload without success, perhaps due to my lack of understanding on how to properly utilize it.

If this answer seems inadequate, please let me know and I will remove the acceptance.

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

TypeScript causing issues when multiple selectors are used

Currently, I have a function that allows me to search for HTML elements based on text content: function findElementsByText(text: string): HTMLElement[] { const selectors = 'button' // This conditional statement ensures that an empty text quer ...

Creating a data structure that filters out specific classes when returning an object

Consider the following scenario: class MyClass {} class MyOtherClass { something!: number; } type HasClasses = { foo: MyClass; bar: string; doo: MyClass; coo: {x: string;}; boo: MyOtherClass; }; type RemovedClasses = RemoveClassTypes& ...

Tips on using class-validator @isArray to handle cases where only a single item is received from a query parameter

Currently, I am attempting to validate a request using class-validator to check if it is an array. The inputs are sourced from query parameters like this: /api/items?someTypes=this This is what my request dto resembles: (...) @IsArray() @IsEn ...

Executing one controller function from another controller in Typescript

There are two typescript controllers in my project Controller A { public methodOfA() {//perform some action} } Controller B { public methodOfB() {//perform some action} } I am trying to implement the following functionality Controller B { ...

Discover the accurate `keyof` for a nested map in TypeScript

Here is the code snippet I'm working on: const functions={ top1: { f1: () => 'string', f2: (b: boolean, n: number) => 1 }, top2: { f3: (b: boolean) => b } } I am looking to define an apply f ...

Tips for adding a mat-error to a mat-input-field on-the-fly

To handle user input exceeding maxLength and dynamically add < mat-error > to the DOM in case of an error, I have implemented an attribute directive that enforces the character limit on input fields. This directive is used across multiple files in the proj ...

Issue encountered when trying to integrate Angular2 with Visual Studio 2015 Update

Starting my journey with Angular2 in Visual Studio 2015. Following advice from this helpful article. Encountering an issue when running the index.html file, it gets stuck on 'Loading...'. Here are the key configurations and code files being use ...

Locating the source and reason behind the [object ErrorEvent] being triggered

I'm facing an issue where one of my tests is failing and the log is not providing any useful information, apart from indicating which test failed... LoginComponent should display username & password error message and not call login when passed no ...

The library "vue-property-decorator" (v10.X) is causing issues with resolving in Webpack despite being successfully installed

Encountered an error message Module not found: Error: Can't resolve './decorators/Emit' while attempting to import functionality from the library vue-property-decorator. The package is installed and accessible, ruling out a simple installati ...

Utilizing Typescript Decorators to dynamically assign instance fields within a class for internal use

I am interested in delving into Typescript Decorators to enhance my coding skills. My primary objective is to emulate the functionality of @Slf4J from Project Lombok in Java using Typescript. The concept involves annotating/decorating a class with somethin ...

I am having issues with the Okta Angular sign-in widget as it is not redirecting

Recently, I integrated the Okta angular sign-in widget into my project, but I encountered an issue. In my application, I have multiple modules including an authentication module that manages sign-in, sign-out, and sign-up functionalities. The route I ult ...

Is it possible to implement a customized pathway for the functions within an Azure function app?

Recently, I set up a new function app on Azure using Azure Functions Core Tools with Typescript as the language. The app includes a test function named MyTestFunction that responds with an HTTP response when called. This particular function is located in ...

TypeScript combines strong typing for arrays into a unified array of objects

I developed a JavaScript function that can merge multiple arrays into an array of objects based on provided key names. Here’s an example: const mergeArraysToSeries = (arrs, keys) => { const merged = []; for (let dataIndex = 0; dataIndex < arrs ...

Exporting ExpressJS from a TypeScript wrapper in NodeJS

I've developed a custom ExpressJS wrapper on a private npm repository and I'm looking to export both my library and ExpressJS itself. Here's an example: index.ts export { myExpress } from './my-express'; // my custom express wrap ...

Resetting the timer of an observable in Angular 2

I have a unique service that automatically calls a method every 30 seconds. There is also a button that allows the user to reset the timer, preventing the method from being called for another 30 seconds. How can I make sure that the method does not get cal ...

The module ~/assets/images/flags/undefined.png could not be found in the directory

When I use the img tag with a dynamic address filled using require, it works well in the component. However, when I try to write a test for it, an error is thrown. console.error Error: Configuration error: Could not locate module ~/assets/ima ...

Troubleshooting a GET Request Hanging Issue with Next.js 13 Route Handler

I'm currently encountering an issue with the new routing feature in my Next.js 13 project. I have a route handler set up in app/api/ingresos/route.ts with the code snippet below: import { NextResponse } from 'next/server'; import PocketBase ...

Simulate a complete class with its constructor, instance methods, and static functions

I have been searching for a comprehensive example that demonstrates how to properly mock all three elements (ClassA constructor, ClassA.func1 instance function, and ClassA.func2 static function) in my TypeScript project. In the code under test, I need to v ...

The react-bootstrap module does not have any members available for export

I'm looking to incorporate the npm module react-bootstrap from this link into my Layout component, following the ASP.NET Core 2.1 template client project structure. The challenge I'm facing is that the template uses a .js file extension, but I pr ...

What could be causing the global npm package to not be utilized for module dependencies?

My typescript and ts-node are already installed globally. In my package.json file, I have the necessary configurations to run tests with npm test. Everything works fine since ts-node and typescript are installed as local modules. { "name": "two_sum", ...