0

I have class below when I call printData I get this.collection is undefined.

How do I access this.collection from the prototype inside printData()? Or do i need to change the class structure. Actually the object returns function which intern returns object in hierarchy.

Thanks in advance!

Sample Class:

var DbProvider = (function () {
    function DbProvider(db) {
        var that = this; // create a reference to "this" object
        that.collection = db;
    }
    DbProvider.prototype.create = function () {
        return {
            action: function () {
                var y = {
                    printData: function () {
                        alert('Hello ' + this.collection.Name);
                    }
                };
                return y;
            }
        };
    };
    return DbProvider;
})();

Usage:

var a = new DbProvider({ "Name": "John" });
a.create().action().printData();
Sumit Deshpande
  • 2,155
  • 2
  • 20
  • 36

3 Answers3

1

Keeping ES5 syntax and the call structure a solution would be:

var DbProvider = (function () {
    function DbProvider(db) {
        var that = this; // create a reference to "this" object
        that.collection = db;
    }
    DbProvider.prototype.create = function () {
        var that = this;
        return {
            action: function() {
                var y = {
                    printData: function () {
                        console.log('Hello ' + that.collection.Name);
                    }
                };
                return y;
            }
        };
    };
    return DbProvider;
})();

Definitely not elegant but it works :)

If you do not want to change your structure, you can achieve this behavior if you change you functions to arrow functions.

var DbProvider = (function () {
    function DbProvider(db) {
        var that = this; // create a reference to "this" object
        that.collection = db;
    }
    DbProvider.prototype.create = function() {
        return {
            action: () => {
                var y = {
                    printData: () => {
                        alert('Hello ' + this.collection.Name);
                    }
                };
                return y;
            }
        };
    };
    return DbProvider;
})();

The way you are creating this "class" is definitely non standard. Let me know if you want an example of how to better structure it.

pppetrov
  • 131
  • 5
  • Thanks for your response. But I am looking for ES5 solution? Is it possible to achieve in ES5? Also please advise if I can restructure the class without changing final caller part i.e.dbProvider.create().action().printData(); – Sumit Deshpande Nov 11 '16 at 17:02
1

just need to keep track of the this pointer correctly, like this

var DbProvider = (function() {
  function DbProvider(db) {
    this.collection = db;
  }
  DbProvider.prototype.create = function() {
    var self = this;
    return {
      action: function() {
        var y = {
          printData: function() {
            alert('Hello ' + self.collection.Name);
          }
        };
        return y;
      }
    };
  };
  return DbProvider;
})();



let dbProvider = new DbProvider({
  Name: "test"
});
dbProvider.create().action().printData();
skav
  • 1,400
  • 10
  • 16
1

You could save the this reference and bind it to the printData function

var DbProvider = (function () {
    function DbProvider(db) {
        var that = this; // create a reference to "this" object
        that.collection = db;
    }
    DbProvider.prototype.create = function () {
        var self = this;
        return {
            action: function () {
                var y = {
                    printData: function () {
                        alert('Hello ' + this.collection.Name);
                    }.bind(self)
                };
                return y;
            }
        };
    };
    return DbProvider;
})();

var a = new DbProvider({ "Name": "John" });
a.create().action().printData();

Or you could refactor a bit and move that to the outer scope of DbProvider and use that in printData

var DbProvider = (function () {
    var that;
    function DbProvider(db) {
        that = this; // create a reference to "this" object
        that.collection = db;
    }
    DbProvider.prototype.create = function () {
        return {
            action: function () {
                var y = {
                    printData: function () {
                        alert('Hello ' + that.collection.Name);
                    }
                };
                return y;
            }
        };
    };
    return DbProvider;
})();

var a = new DbProvider({ "Name": "John" });
a.create().action().printData();
taguenizy
  • 2,140
  • 1
  • 8
  • 26