0

Hi i am beginning using the singleton javascript design pattern, but i have some scope problems. Here i am just experimenting with a small ajax, retrieve and store singleton. From within a function in the singleton i call another function (this.ready, called when the ajax has retrieved and stored the data) but it seems "this" doesn't refer to the singleton, rather it refers to "Object #XMLHttpRequest" according to chrome debugger, firefox just says it's undefined.

            var mag = {
                magObj: [], // object to store the retrieved json data

                getData: function(){
                    request = getHTTPObject(), // defined externally
                    request.onreadystatechange = this.setData;
                    request.open("POST", "be.php", true);
                    request.send(null);
                },

                setData: function(){  
                    if (request.readyState == 4)
                    {
                        this.magObj = JSON.parse(request.responseText);
                        this.ready(); // this line yields the error, seems "this" does not refer to the singleton

                    }
                    else if (request.readyState == 1)
                    {

                    }
                },

                ready: function() {
                    console.log('ready');
                },

                construct: function(){
                    this.getData();
                },  
            }

Also if i try to declare the getHTTPObject() as a singleton variable in the top, instead of using global variable i get the error Cannot read property 'readyState' of undefined. Again it's "this" getHTTPObject that seems to be undefined even though i set it at the top:

        var mag = {
            magObj: [],
            request: getHTTPObject(),

            getData: function(){

                this.request.onreadystatechange = this.setData;
                this.request.open("POST", "be.php", true);
                this.request.send(null);
            },

            setData: function(){  
                if (this.request.readyState == 4) // debugger says this.request is undefined
                {
                    this.magObj = JSON.parse(this.request.responseText);

                }
                else if (this.request.readyState == 1)
                {

                }
            },

            construct: function(){
                this.getData();
            },  
        }
1

3 Answers 3

1

If it is a singleton you could try

           var mag = {
            magObj: [], // object to store the retrieved json data

            getData: function(){
                request = getHTTPObject(), // defined externally
                request.onreadystatechange = this.setData;
                request.open("POST", "be.php", true);
                request.send(null);
            },

            setData: function(){  
                if (request.readyState == 4)
                {
                    this.magObj = JSON.parse(request.responseText);
                    mag.ready(); // this line yields the error, seems "this" does not refer to the singleton

                }
                else if (request.readyState == 1)
                {

                }
            },

            ready: function() {
                console.log('ready');
            },

            construct: function(){
                this.getData();
            },  
        }
Sign up to request clarification or add additional context in comments.

Comments

1

#1
setData is a callback function for the XMLHttpRequest object. It's therefore run in the scope of the XMLHttpRequest object. Use mag instead of this.

#2
Same as #1: this refers to the XMLHttpRequest, rather than you mag variable.

Comments

1

To solve the scope problem, you need to use the concepts of closures in javascript. basically a scope where functions have access to properties and methods in the context that created that function.. ok for a more clear explanation.. try initializing your mag object as a function..

var mag = function(){
    var magObj = [];
    var getData = function(){
        //here you'll have access to the magObj collection
    };
}

The previous is a classic example of a javascript closure.. Of course you instantiate the mag object simply as a function invocation mag();

Hope this helps.

Comments

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.