11

I am porting some javascript code over to typescript and I have come across a problem.

I have an ajax call which passes an object as context, this object contains some callbacks and some other information which are read out by the success or error callbacks which indicate where the success invocation should be redirected to:

function SomeAjaxService
{
    var self = this;

    self.CheckErrorType = function(...) {
        // Do something
    };

    var SuccessProxyCallback = function(results) {
        // Do some stuff with results, like send off some events
        this.successCallback(results);
    };

    var FailureProxyCallback = function(...) {
        // Do some stuff with errors, and fire some events
        var someErrorType = self.CheckErrorType(...);
        this.failureCallback(someErrorType);        
    };

    self.SendRequest = function(requestArgs) {
        var ajaxSettings = {
            context: requestArgs,
            // Assign a load of stuff
        };

        $.ajax(ajaxSettings);
    };
}

Now as you can see the failure proxy calls a local method as well as a using the "this" context object. So how can you handle this sort of scenario with typescript?

Can you just set self = this in the constructor and continue as you were before?

== EDIT ==

As requested here is a class representation of above showing the issue of this needing to be 2 things due to the missing self variable.

class SomeAjaxService
{
    public CheckErrorType(someArg1: any, someArg2: any) {
        // Do some stuff with data
    };

    private SuccessProxyCallback(results: any) {
        // Do some stuff with results, like send off some events
        this.successCallback(results); 

        // Does the above *THIS* usage point to the context of the 
        // Ajax call or the actual instantiated class
    };

    private FailureProxyCallback(...) {
        // Do some stuff with errors, and fire some events
        var someErrorType = this.CheckErrorType(...);

        // The above *THIS* call cannot be correct if the context has overwritten
        // the scope of this, however I dont know if this is true, do I even need
        // this.CheckErrorType to invoke a local method?

        this.failureCallback(someErrorType);        

        // As mentioned above same issue here but the *THIS* should hopefully
        // point to the context object on the ajax object not the local instance.
    };

    public SendRequest(requestArgs: any) {
        var ajaxSettings : JqueryAjaxSettings = {
            context: requestArgs,
            // Assign a load of stuff
        };

        $.ajax(ajaxSettings);
    };
}

Like I say above the main issue is that in a method I need to invoke one of the instances methods as well as invoke a method on the context object from the ajax call. With raw javascript I would have self = this and then I can get around this being overridden, which is required to keep the ajax async state object in scope.

3
  • The TypeScript compilation of this code is exactly this code itself, so what you really have here is a JavaScript question. Or are you trying to convert this to a class (if so, what do you have so far)? Commented Mar 27, 2013 at 15:04
  • This is the original javascript, well this is a mocked up set of javascript to show the problem I have. I will update with a mock typescript class if it will help, although I thought the problem would be apparent without it. Commented Mar 27, 2013 at 15:07
  • This might help youtube.com/watch?v=tvocUcbCupA&hd=1 Commented Apr 21, 2014 at 5:33

1 Answer 1

8

Can you just set self = this in the constructor and continue as you were before?

Speaking abstractly, doing this in the constructor will usually solve nothing (unless you capture it later on in that method -- see below). TypeScript classes store class instance data on the object itself rather than capturing locals. Because self will be stored on the this object, you don't end up having anything you didn't already have before.

Here's one way to do it:

class SomeAjaxService
{
    private FailureProxyCallback(context, arg) {
        // now 'this' is the class instance and 'context' is requestArgs 
    }

    public SendRequest(requestArgs) {
        var self = this; // Note: captured local used in closure below
        var ajaxSettings = {
            context: requestArgs,
            // Do not use an arrow function here, even though it's tempting!
            error: function(arg) { self.FailureProxyCallback(this, arg) }
        };

        $.ajax(ajaxSettings);
    };
}
Sign up to request clarification or add additional context in comments.

1 Comment

What is the problem of using the lambda expression (arrow function) ?

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.