2

I'm making a Grid with the new standard ES6 using classes to be able to extend functionality in the future and the jquery method $.ajax. Everything worked great until I started to have scope problems. I want to call a method of the class from within an ajax call. How do I do that?. I tried using this.method(), method()....but no luck.....I also tried to bind the method in the constructor method.....

this.generateGridHeader=this.generateGridHeader.bind(this);

without any luck as well....

This is the code, the problem is in the buildGrid() method in the success callback function, the call to generateGridHeader() and generateGridBody().....they are not being recognized....I'm aware that it's not finding them because of the this that is not the right scope, but I don't know how to reference the class methods from within there.....

class Grid{

constructor(gridOptions) {
 this.grid_header='';
 this.grid_body='';
 this.grid='';   
 this.options=gridOptions;
 this.cacheDom();
 //this.bindEvents();
 this.buildGrid();
 //I need to bind them cause I'm going to use them inside a callback function
 //this.generateGridHeader=this.generateGridHeader.bind(this);
 //this.generateGridBody=this.generateGridBody.bind(this);
}

cacheDom() {
   this.$greeder = $(this.options.selector);
} 

bindEvents() {

}

buildGrid(){

 if(this.options.parameters !== undefined){
    //it's an ajax call
 $.ajax({
        method: "POST",
        url: this.options.data,
        data: $.param(this.options.parameters),
        success: function(data) {

            this.generateGridHeader();

             this.generateGridBody(data);

            // generateGrid(data, options); 
           // styleGrid(options);  //it can be default with bootstrap if the property style is undefined, if the user wants to put his own style he can use style:'custom' parameter
           // generatePager(options);
           // renderGrid(options);

        }
    });

 }else{
    //it's fixed data from an array or object
    //if typeof == Array parse array
    //if typeof == Object parse object
 }

}

  generateGridHeader(){

    var fields=this.options.fields;
    var header;

    header='<thead><tr>';

     $.each(fields, function(i, item) {
        header+='<th>'+fields[i].title+'</th>';
      });

     header+='</tr></thead>';
     alert(header);

    this.header=header;
}

generateGridBody(data){

} 

styleGrid(){

}    

renderGrid() {

}

}

/* dataType: 'array', 'json'possible values, if parameters is not defined it's array mode*/
var grid= new Grid({
    title:'The grid',
    selector:'#grid',
    data:'./api/getCustomers.php',
    parameters: {"id_customer":"32"},
    fields:{
        id_customer:{
         title:'ID customer'
        },
        first_name:{
         title:'First Name' 
        },
        last_name:{
         title:'Last Name'  
        }       
    }   
});
John
  • 1,711
  • 2
  • 29
  • 42
  • 1
    I would suggest trying to bind the success function. i.e `success: function() { ... }.bind(this)` – Gilad Artzi May 26 '16 at 16:08
  • 1
    Just prior to `$.ajax()` you could create a new var `var _that = this;` then use `_that.generateGridHeader()` and `_that.generateGridBody(data)` in your `success()` function. Or you could add a `context: this` to your `$.ajax()` properties. – mferly May 26 '16 at 16:20
  • Thanks to both. I ended up using the `context: this` option that Marcus suggested. I didn't know that option. Please, post it as an answer so I can mark it as the solution....Thanks again! – John May 26 '16 at 16:45
  • I've added it as an answer below. Glad I could help. – mferly May 26 '16 at 16:55
  • You don't have to bind the `generateGridHeader` and `generateGridBody` methods that you are calling from the callback, but rather the callback itself. Btw, since you're asking about ES6, just use an arrow function for the callback. – Bergi May 26 '16 at 18:01

1 Answers1

3

Add context: this to your $.ajax() settings. This (context) object will be the context of all Ajax-related callbacks thereafter.

$.ajax({
    method: "POST",
    url: this.options.data,
    context: this,
    ...

Now within the success() callback function, this, when calling this.generateGridHeader(); and this.generateGridBody(data); will work as expected as it holds the correct object (context).

See jQuery.ajax()#context for more details.

mferly
  • 1,646
  • 1
  • 13
  • 19