5

I have the below TypeScript class.

export class BrandViewModel {

        private _items = ko.observableArray();

        public Add(id: number, name: string, active: boolean) : void {
            this._items.push(new BrandItem(this, id, name, active));
        }

        public Get() : void  {
            $.get("/api/brand", function(items) {
                $.each(items, function (i, item) {
                        this.Add(item.Id, item.Name, item.Active);
                    });
            }, "json");
        }
}

The resulting javascript for the Get method is:

    BrandViewModel.prototype.Get = function () {
        $.get("/api/brand", function (items) {
            $.each(items, function (i, item) {
                this.Add(item.Id, item.Name, item.Active);
            });
        }, "json");
    };

I have seen in the TypeScript documentation that I can do this:

    public Get() : void  {
        $.get("/api/brand", () => function(items) {
            $.each(items, function (i, item) {
                    this.Add(item.Id, item.Name, item.Active);
                });
        }, "json");
    }

Which results in the below, where _this is now a reference to the BrandViewModel instance but the this inside the jquery .each function is not changed to _this as I might expect:

    BrandViewModel.prototype.Get = function () {
        var _this = this;
        $.get("/api/brand", function () {
            return function (items) {
                $.each(items, function (i, item) {
                    this.Add(item.Id, item.Name, item.Active);
                });
            };
        }, "json");
    };

Instead I have done the below in TypeScript:

    public Get(): void {
        var _this = this;
        $.get("/api/brand", function(items) {
            $.each(items, function (i, item) {
                    _this.Add(item.Id, item.Name, item.Active);
                });
        }, "json");
    }

which gives me the result I wanted:

    BrandViewModel.prototype.Get = function () {
        var _this = this;
        $.get("/api/brand", function (items) {
            $.each(items, function (i, item) {
                _this.Add(item.Id, item.Name, item.Active);
            });
        }, "json");
    };

Does anyone know a more appropriate way to do this?

1

2 Answers 2

11

You can do this:

    public Get() : void  {
        $.get("/api/brand", (items) => {
            $.each(items, (i, item) => {
                    this.Add(item.Id, item.Name, item.Active);
                });
        }, "json");
    }

Which generates:

    BrandViewModel.prototype.Get = function () {
        var _this = this;
        $.get("/api/brand", function (items) {
            $.each(items, function (i, item) {
                _this.Add(item.Id, item.Name, item.Active);
            });
        }, "json");
    };
Sign up to request clarification or add additional context in comments.

4 Comments

Very nice, thank you. Any chance of a bit of explanation on how that works as it does? i.e. knows to place the _this outside of both functions?
That gets generated when you use the fat arrow notation I.e. ()=>{}
@basarat what I am asking though is the fat arrow notation is being used twice and nested.. how does _this get put in the correct place.
@Pricey typescript will generate it at the top of a fat arrow chain. If you have a function() in between then that chain will break.
0

Consistent with ECMAScript 6 arrow functions, TypeScript lexically binds this when using =>.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.