0

If you see something here that you think could be improved upon, please let me know!

The Problem: I'm trying to accomplish a basic structure of processing some Json data through a mootools class. What I'm currently running into is when I call 'this.processObj' I receive 'processObj is not defined'

Code:

this.runSomeJson= new Class({

    Implements: [Options, Events],

    options: {
        contentInfo: false,
    },
    initialize: function(element, options) {
        this.element = document.id(element);
        if (!this.element) return;
        this.setOptions(options);
        this.setBasicInfo();
    },
    setBasicInfo: function () {
        var callThis = 'somegenericurl';
        this.getObj(callThis);
    },
    getObj: function (callThis) {
        var jsonReq = new Request.JSON({
          method: 'get',
          url: callThis,
          onRequest: function () {
            console.log('Loading: ' + callThis);
          },
          onComplete: function(thisObj){
            //console.log(thisObj);
            this.processObj(thisObj);
          }
        }).send();  
    },
    processObj: function (thisObj) {
        console.log('in process..');
    },
});

1 Answer 1

7

the binding of this in an onComplete of a request is the Request Instance itself, not your original scope.

there are 3 patterns you can use.

1. saving a reference

getObj: function (callThis) {
    var self = this;
    new Request.JSON({
      method: 'get',
      url: callThis,
      onRequest: function () {
        console.log('Loading: ' + callThis);
      },
      onComplete: function(thisObj){
        // call it on the self reference
        self.processObj(thisObj);
      }
    }).send();  
},

2. binding the anonymous function

you can use the function.bind decorator to change scope within the callback:

getObj: function (callThis) {
    new Request.JSON({
      method: 'get',
      url: callThis,
      onRequest: function () {
        console.log('Loading: ' + callThis);
      },
      onComplete: function(thisObj){
        //console.log(thisObj);
        this.processObj(thisObj);
      }.bind(this) // change scope, inner this becomes the outer this as well.
    }).send();  
},

3. move to the method on the class and bind directly

this skips the anon function creation.

getObj: function (callThis) {
    new Request.JSON({
      method: 'get',
      url: callThis,
      onRequest: function () {
        console.log('Loading: ' + callThis);
      },
      onComplete: this.processObj.bind(this)          
    }).send();  
},

in terms of preference: I'd choose #1 as it has the smallest performance footprint, it is the preferred mootools way [tm]. then probably #3 for best code organisation.

there is a 4th way in conjunction with the binds class mutator from mootools-more but let's not do that :)

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

3 Comments

very complete answer, I've got a mix of 1 and ahum 4, I know bind uses alot of processing from using the profiler so I suppose I got some rewriting to do
Perfect, thanks so much Dimitar also want to thank you for all the information on your site! Truthfully been learning alot!
no worries, I enjoy it as it helps me too - seeing 100s of problems that are new to me, new patterns, new ideas, documenting all of it...

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.