Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript - TypeError myclass.myFunction is not a function

I'm facing an issue with the following code.

What it basically should do. It should load and parse a given JSON file. And in the RequestListender it should show the ID and the string Hello which is returned by the ToString() method in Product.ts. Where the tProduct.Id is shows up correctly, the tProduct.ToString() method fails with the error stated below.

Thanks a lot in advance.

Error message:

TypeError: tProduct.ToString is not a function.   (In 'tProduct.ToString()', 'tProduct.ToString' is undefined) 

File: Test.ts

var currentProduct = null as pvis.Product;  function runTest(path) {     var request = new XMLHttpRequest();     request.onload = loadRequestListener;     request.open("get", path, true);     request.send(); }  function loadRequestListener () {     var tProduct : pvis.Product = JSON.parse(this.responseText);     if (tProduct.Id) {         currentProduct = tProduct;         alert('loaded with Id: ' + tProduct.Id );            alert('loaded with Content: ' + tProduct.ToString() );       }     else {         alert('product failed to load');     }  } 

File Product.ts

module pvis {     export class Product {          Id: string;          ToString():string {             return 'Hello';         }     } } 

The HTML part:

<body onload="runTest('assets/products/json/A379N.json')"> 

The compiled Javascript:

var pvis; (function (pvis) {     var Product = (function () {         function Product() {         }         Product.prototype.ToString = function () {             return 'Hello';         };         return Product;     })();     pvis.Product = Product; })(pvis || (pvis = {})); var currentProduct = null; function runTest(path) {     var request = new XMLHttpRequest();     request.onload = loadRequestListener;     request.open("get", path, true);     request.send(); } function loadRequestListener() {     var tProduct = JSON.parse(this.responseText);     if (tProduct.Id) {         currentProduct = tProduct;         alert('loaded with Id: ' + tProduct.Id);         alert('loaded with Content: ' + tProduct.ToString());     }     else {         alert('product failed to load');     } } 

The tsconfig.json (I'm not sure if it is relevant):

{     "compilerOptions": {         "target": "ES5",         "removeComments": true,         "preserveConstEnums": true,         "out": "js/main.js",         "sourceMap": true     },     "files": [        "src/Test.ts"     ] } 
like image 947
frank Avatar asked Dec 01 '15 22:12

frank


People also ask

Why is my JavaScript function undefined?

A variable that has not been assigned a value is of type undefined . A method or statement also returns undefined if the variable that is being evaluated does not have an assigned value. A function returns undefined if a value was not returned .

Is not a function Typeerror TypeScript?

This is a standard JavaScript error when trying to call a function before it is defined. This error occurs if you try to execute a function that is not initialized or is not initialized correctly. This means that the expression did not return a function object.

Is not a function in is undefined?

This is a common JavaScript error that happens when you try to call a function before it is defined. You get this error when you try to execute a function that is uninitialized or improperly initialized . It means that the expression did not return a function object.


1 Answers

The line:

var tProduct : pvis.Product = JSON.parse(this.responseText); 

is wrong. The reason it compiles is only due to JSON.parse returning any.

to use the class Product you have to create an instance of it somehow. JSON parse will not do this, it will simply return an object with the parsed JSON in it, it will not be an instance of the pvis.Product class.

If what you want to do is type the JSON result you can do that with an interface. For example if you have a JSON object on the form:

{     id: "some value",     name: "some name",     count: 4 } 

You can type that with the interface:

interface myInterface {     id: string;     name: string;     count: number; } 

And use it like so:

var myParsedAndTypedJson: myInterface = JSON.parse("...."); 

An object created like that will never have methods however, if you want that functionality you have to pass this information in to a class that can use it some how, for example;

class myClass implements myInterface {      get id(): string { return this.initData.id; }     get name(): string { return this.initData.name; }     get count(): number { return this.initData.count; }      constructor(private initData: myInterface) {      }      public ToString() {         return this.id + ' ' + this.name + ' ' + this.count;     } } 

Working example of this can be found here.

You might want to look up how to work with typescript interfaces and JSON to learn a bit more about how this works.

like image 162
Nypan Avatar answered Oct 02 '22 15:10

Nypan