Starboy
Starboy

Reputation: 1635

Mootools Class, json processing / function not defined

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..');
    },
});

Upvotes: 0

Views: 327

Answers (1)

Dimitar Christoff
Dimitar Christoff

Reputation: 26165

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 :)

Upvotes: 7

Related Questions