0

I created a class in JavaScript as follows:

class TreeMatching
{
        constructor()
        {
            this.thresholdPoints=0;
            this.neighborWeight = 0.4;
            this.totalFrequency = 0.0;
            this.listSeq = [];
            this.listFreq = [];
            this.mapScore = new Object();
            this.tree = new Trie();
        }

        createTree()
        {
            var list_Dictionary;
            var loadWordList = $.get("../wordFrequencyTop5000.txt", function(data)
            {
                list_Dictionary = data.split("\n");
            });

            loadWordList.done(function()
            {
                for(var i=0;i<list_Dictionary.length;i++)
                {
                    var string = list_Dictionary[i];
                     this.tree.insert(string); //<-- Cannot read property 'insert' of undefined
                }
            });

       }
}

which is supposed to call the insert method in class Trie as follows:

class Trie
{
        constructor()
        {
            this.count=1;
            this.root = new TrieNode();
        }

        insert(word)
        {
            var children = new Object();

            for(var i=0; i<word.length(); i++){
                var c = word.charAt(i);

                var t;
                if(children[c]){
                        t = children[c];
                }else{
                    t = new TrieNode(c);
                    children.put(c, t);
                }

                children = t.children;

                //set leaf node
                if(i==word.length()-1)
                    t.isLeaf = true;   
            }
        }
}

However, the line of code where the error is marked, the outer function's this value, is not having properties tree, mapScore, etc.

Is there a way that I can access those values from the inner callback function?

Thanks

Techs
  • 119
  • 1
  • 8

3 Answers3

1

look at 'this' - you will have to define local variable to maintain reference to "this" inside the call, as described in the link.

createTree()
        { 
            var self = this;
            var list_Dictionary;
            var loadWordList = $.get("../wordFrequencyTop5000.txt", function(data)
            {
                list_Dictionary = data.split("\n");
            });

            loadWordList.done(function()
            {
                for(var i=0;i<list_Dictionary.length;i++)
                {
                    var string = list_Dictionary[i];
                     self.tree.insert(string); //<-- Now you should be able to do it
                }
            });

       }
Community
  • 1
  • 1
Vladimir M
  • 3,972
  • 1
  • 15
  • 21
0

'this' in the inner anonymous has different scope. Try to use the advantage of closer in JS which will get access to the function caller scope.

var that = this;
loadWordList.done(function() {
    for(var i=0;i<list_Dictionary.length;i++)
    {
         var string = list_Dictionary[i];
         that.tree.insert(string); // 'that' will hold 'this' in the right scope
    }
});
Yoram
  • 532
  • 6
  • 15
0

The anonymous function inside loadWordlist.done creates a new scope with an new context.

if you want to keep the old context you can use the ES2015 arrow function:

loadWordList.done(() => {
    //code here
);

or make a var inside createTree() like this:

var that = this;

and then inside the loadWordList callback you can refer to the right context using:

that.tree.insert(string);

I personally prefer the arrow function because 'that' is a lousy choice for a var name. And since your using the ES2015 classes browser support must not be an issue.

Barry127
  • 1,120
  • 1
  • 10
  • 22