xDreamCoding
xDreamCoding

Reputation: 1694

jQuery Callback inside Typescript Class

Got a Problem with Typescript and jQuery. The elements get appended to body and show up but nothing happens when i click the button.

I suppose its something with the this.fooClick() that gets passed to the button but doesnt get called or the wrong jquery elements gets saved to the class variables.

Anyone help?

test.ts

/// <reference path="jquery.d.ts" />

class foo {

    private button;
    private text;

    constructor() {

        this.button = $('<button>').html("click").click(this.fooClick());
        this.text = $('<p>').html("foo");

        $('body').append(this.button);
        $('body').append(this.text);
    }

    public fooClick() {
        $(this.text).html("bar");
    }

}

$(function() {
    var foobar = new foo();
})

test.js

/// <reference path="jquery.d.ts" />
var foo = (function () {
    function foo() {
        this.button = $('<button>').html("click").click(this.fooClick());
        this.text = $('<p>').html("foo");
        $('body').append(this.button);
        $('body').append(this.text);
    }
    foo.prototype.fooClick = function () {
        $(this.text).html("bar");
    };
    return foo;
})();
$(function () {
    var bar = new foo();
});

Upvotes: 2

Views: 4355

Answers (2)

cspotcode
cspotcode

Reputation: 1892

When registering the click handler, you must pass it a reference to the callback, not invoke the callback. Invocation will happen when the button is actually clicked.

Hence, you should do:

this.button = $('<button>').html("click").click(this.fooClick);
// notice the removed parentheses

Since fooClick expects its this value to be bound to the instance of foo, you should also rewrite it as an arrow function:

public fooClick = () => {
    $(this.text).html("bar");
}

Upvotes: 2

David Sherret
David Sherret

Reputation: 106820

When you call .click() you want to pass it a function that can be executed when the button is clicked. Right now you are immediately executing your function:

this.button = $('<button>').html("click").click(this.fooClick());

...which will pass in the result of this.fooClick() which is undefined.

You can solve this, by passing in a function that will be executed later:

this.button = $('<button>').html("click").click(() => this.fooClick());

Note: As shown, make sure you use an arrow function to preserve the context of this.

Upvotes: 5

Related Questions