Vikram Anand Bhushan
Vikram Anand Bhushan

Reputation: 4896

JS returning function not present

I have following code.

var handleJson = function(){
        var jsonData ='xx';
        var eventObject,eventObjectx=[];
        that = this;
        var convertJsonToObject = function(datax){
                //debugger;
                try {
                        that.printList(datax.data);
                    } catch(e) {
                      console.log(e);
                    }

                //debugger;
            }

        return{

            getDatafromserver: function(url){

                    $.ajax({
                        crossOrigin: true,
                        url: url,
                        success:convertJsonToObject
                            //console.log(jsonData);
                    });

            },

            printList:function(eventObject){

                $.each(eventObject,function(index,val){

                    $('#eventlist').append('<li>'+val.event+'</li>');
                })
            }

        }
    }


    var jsonHandler = new handleJson();

        jsonHandler.getDatafromserver(url);

        //jsonHandler.printList('eventlist');


});

Although the function printList exist its returning error

TypeError: that.printList is not a function {stack: (...), message: "that.printList is not a function"}

Can any one help me out?

Upvotes: 0

Views: 48

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1075219

The value of this as of your that = this line is not in any way related to the object that you return at the end of your handleJson function.

Since you're using new with handleJson, you want to add to the object that this refers to, rather than returning a new, unrelated object:

var handleJson = function() {
    var jsonData = 'xx';
    var eventObject, eventObjectx = [];
    var that = this;
    var convertJsonToObject = function(datax) {
        //debugger;
        try {
            that.printList(datax.data);
        } catch (e) {
            console.log(e);
        }

        //debugger;
    }

    this.getDatafromserver = function(url) {

        $.ajax({
            crossOrigin: true,
            url: url,
            success: convertJsonToObject
                //console.log(jsonData);
        });

    };

    this.printList = function(eventObject) {

        $.each(eventObject, function(index, val) {

            $('#eventlist').append('<li>' + val.event + '</li>');
        })
    };

};

var jsonHandler = new handleJson();

jsonHandler.getDatafromserver(url);

//jsonHandler.printList('eventlist');

Here's how new works:

  • It creates a new object backed by the object that the target function's prototype property refers to; so in your case, a new object backed by handleJson.prototype.
  • It calls the target function (handleJson) with this referring to that new object.
  • When the target function returns, if it doesn't return anything, or it returns a primitive value, or it returns null, new takes the object that it created as its result; but if the target function returns a non-null object reference, that overrides that default and new takes that object reference as its result.

In your original code, that last point was coming into play.


Side note: Your code was falling prey to The Horror of Implicit Globals becuse you weren't declaring that. I've added var on it above.


Side note: The overwhelming convention in JavaScript is that a constructor function (a function you're calling via new) starts with a capital letter. They're also usually nouns rather than verbs (other kinds of functions are usually verbs, but not constructor functions, which are named after the thing they construct). So JsonHandler rather than handleJson.

Upvotes: 1

Related Questions