2

so I have created a small table row generator from JSON. When I started building it I hadn't put it in an object and it worked absolutley fine.

After, I made it so it could be abstract and just needes parameters passed to it. Then I put it in an object so that I could easily re use it for other sets of data. However, after putting it in an object I get the console message:

TypeError: this.getTableRow is not a function

But... it is a function:

getTableRow: function(data) {
    row = "<tr>";

    for (i in data) {
        row += "<td>" + data[i] + "</td>";
    }

    row += "</tr>";

    return row;
}

Here is the full script so you have it in context:

var dataCollector = {

    baseDataURL: 'http://tourn.dev/data/',

    displayDataTable: function(dataPath, tableIdentifier, dataKeys, dataOpts) {

        $.getJSON(this.buildPath(dataPath, dataOpts), function (dataset) {
            for (k in dataset) {

                d = dataset[k];

                data = [];

                for (i in dataKeys) {
                    data[i] = d[dataKeys[i]];
                }
                ;

                $(tableIdentifier).append(this.getTableRow(data));
            }
        })
    },

    getDataURL: function() {
        return this.baseDataURL;
    },

    buildPath: function(dataPath, dataOpts) {
        path = this.getDataURL();

        if (dataPath != null) {
            path += dataPath;
        }

        if (dataOpts != null) {
            if (dataOpts.constructor === Array) {
                for (i in dataOpts) {
                    path += '/' + dataOpts[i];
                }
            } else {
                path += '/' + dataOpts;
            }
        }

        return path;
    },

    getTableRow: function(data) {
        row = "<tr>";

        for (i in data) {
            row += "<td>" + data[i] + "</td>";
        }

        row += "</tr>";

        return row;
    }
};
Dominic Sore
  • 397
  • 2
  • 4
  • 14

3 Answers3

3

this.getTableRow is not anything inside the getJSON context. Store this outside the call.

displayDataTable: function(dataPath, tableIdentifier, dataKeys, dataOpts) {
    var self = this; // store this
    $.getJSON(this.buildPath(dataPath, dataOpts), function (dataset) {
        for (k in dataset) {

            d = dataset[k];

            data = [];

            for (i in dataKeys) {
                data[i] = d[dataKeys[i]];
            }
            ;

            $(tableIdentifier).append(self.getTableRow(data)); //this in correct scope
        }
    })
}

More info about scope here: http://javascriptplayground.com/blog/2012/04/javascript-variable-scope-this/

CosX
  • 1,920
  • 2
  • 15
  • 25
2

Inside the $.getJSON callback, this does not refer to dataCollector, but to the jqXHR object.

Please see How to access the correct `this` context inside a callback? for solutions.

Also related: $(this) inside of AJAX success not working

Community
  • 1
  • 1
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
0

It's because each function you create have different this context, if it's not an object then it's global window object, unless you have strict mode, try to use dataCollector isntead of this.

var dataCollector = {

    baseDataURL: 'http://tourn.dev/data/',

    displayDataTable: function(dataPath, tableIdentifier, dataKeys, dataOpts) {

        $.getJSON(this.buildPath(dataPath, dataOpts), function (dataset) {
            for (k in dataset) {

                d = dataset[k];

                data = [];

                for (i in dataKeys) {
                    data[i] = d[dataKeys[i]];
                }
                ;

                $(tableIdentifier).append(dataCollector.getTableRow(data));
            }
        })
    },
jcubic
  • 61,973
  • 54
  • 229
  • 402