14

I'm trying to call a instance method of a TypeScript class (in an ASP.NET MVC project). However, at Runtime I get exceptions like 0x800a01b6 - JavaScript runtime error: Object doesn't support property or method 'checkString'.

I copied the generated JavaScript in a jsfiddle where the method seems to work.
I'm not really a JavaScript guy, so any help is much appreciated!

Things I have tried so far:

  1. different browsers (Chrome: Uncaught TypeError: undefined is not a function, FF: TypeError: this.checkString is not a function)
  2. clearing browser caches
  3. deleting the temporary files of IIS Express
  4. cleaning and rebuilding the solution
  5. not using the private modifier
  6. starting the project on another machine
  7. replacing the underscore.js call with a dummy to verfiy that's not the problem
  8. checked that the instance members are correctly set

This is the TypeScript code:

class FormData {
    BlogName: string;
    CacheTimeOut: number;
    CopyrightHolder: string;
    NavBarTitle: string;
    MarkdownExtra: boolean;
    MarkdownSanitize: boolean;
    RatingActive: boolean;
    HtmlEditor: boolean;

    constructor(blogName: string, cacheTimeOut: number, copyrightHolder: string, navBarTitle: string, markdownExtra: boolean, markdownSanitize: boolean, ratingActive: boolean, htmlEditor: boolean) {
        this.BlogName = blogName;
        this.CacheTimeOut = cacheTimeOut;
        this.CopyrightHolder = copyrightHolder;
        this.NavBarTitle = navBarTitle;
        this.MarkdownExtra = markdownExtra;
        this.MarkdownSanitize = markdownSanitize;
        this.RatingActive = ratingActive;
        this.HtmlEditor = htmlEditor;
    }

    private checkString(value: string): boolean {
        return _.isString(value) && value !== '';
    }

    validate(): boolean {
        return (this.checkString(this.BlogName) && this.checkString(this.CopyrightHolder) && this.checkString(this.NavBarTitle) && _.isNumber(this.CacheTimeOut) && !_.isNull(this.MarkdownExtra) && !_.isNull(this.MarkdownSanitize) && !_.isNull(this.RatingActive));
    }       
}

//I'm calling the validate function like that (from within the same module)
var form = getFormData(); //returns a FormData instance
if (!form.validate()) {
    //foo
}

And here the generated JavaScript:

var FormData = (function () {
    function FormData(blogName, cacheTimeOut, copyrightHolder, navBarTitle, markdownExtra, markdownSanitize, ratingActive, htmlEditor) {
        this.BlogName = blogName;
        this.CacheTimeOut = cacheTimeOut;
        this.CopyrightHolder = copyrightHolder;
        this.NavBarTitle = navBarTitle;
        this.MarkdownExtra = markdownExtra;
        this.MarkdownSanitize = markdownSanitize;
        this.RatingActive = ratingActive;
        this.HtmlEditor = htmlEditor;
    }
    FormData.prototype.checkString = function (value) {
        return _.isString(value) && value !== '';
    };

    FormData.prototype.validate = function () {
        return (this.checkString(this.BlogName) && this.checkString(this.CopyrightHolder) && this.checkString(this.NavBarTitle) && _.isNumber(this.CacheTimeOut) && !_.isNull(this.MarkdownExtra) && !_.isNull(this.MarkdownSanitize) && !_.isNull(this.RatingActive));
    };
    return FormData;
})();

2 Answers 2

31

This is probably because of the wrong this at runtime. You can use a lambda function ()=>{} instead of function to make sure that the this is lexically scoped in the generated JavaScript:

validate = (): boolean => {
        return (this.checkString(this.BlogName) && this.checkString(this.CopyrightHolder) && this.checkString(this.NavBarTitle) && _.isNumber(this.CacheTimeOut) && !_.isNull(this.MarkdownExtra) && !_.isNull(this.MarkdownSanitize) && !_.isNull(this.RatingActive));
    } 

Please search for what this means in javascript and typescript to learn more.

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

2 Comments

Thank you, I was facing the same issue when calling a function as a Jquery Event. The "this" was referring to the event and not the class. Your solution resolved my issue. It still does not explain why this is happening in Typescript. There must be another way.
I just had this problem six years later. Shocking and disappointing how it wasn't fixed by now
6

Another Bypass-Style Solution:
instead of using this., you can use super..

  • A prerequisite is to create two classes, one as a Base Class, another as a Usable Class.
  • The Base Class contains the methods that you want to call in the constructor.
  • The Usable Class calls the Method from within it's constructor using super.myMethod(); instead of this.myMethod();

This is a subtle benefit made easily possible thanks to Typescript. :)

Example:
Source: Typescript Bypass Solution on Stackoverflow

export class myBaseClass
{
    constructor(ctx:any)
    {
        this.ctx = ctx;         // Audio context saved into member variable of class
    }
    myBaseMethod()
    {
        // Do Complex Work
    }
}

export class myUsableClass extends myBaseClass
{
    constructor(ctx:any)
    {
        super(ctx);
        super.myBaseMethod(); // Use super., Not this.
    }

}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.