When trying to access a nested function, "undefined is not a function"

I am working on some end-to-end tests using JavaScript (Protractor). I have a PageObjects file that contains the following:

var SomeClass = function() {
    this.get = function() {
        browser.get('http://blah');
    };

    this.person = function() {
        var firstNameInput = element(by.id('firstName'));
        var lastNameInput = element(by.id('lastName'));

        this.setTitle = function(title) {
            element(by.xpath('//select[@id="title"]/option[text()="' + title +'"]')).click();
        };

        this.setFirstName = function(firstName) {
            firstNameInput.sendKeys(firstName);
        };

        this.setLastName = function(lastName) {
            lastNameInput.sendKeys(lastName);
        };
    };
};

module.exports = new SomeClass();

      

In my spec, I'm trying to access a nested function like this:

describe('some test', function() {
    var someClass = require('./some_class.po.js');
    var data = require('./some_class.data.json');

    it('do stuff', function() {
        someClass.get();
        someClass.person.setTitle(data.title);
        someClass.person.setFirstName(data.firstName);
        someClass.person.setLastName(data.lastName);
    });
});

      

When I try to run this test, the higher level someClass.get()

works just fine, but when it tries to run someClass.person.setTitle(data.title)

I get a message Failed: undefined is not a function

.

Any idea what I am doing wrong? I am using setters, no getters. Don't feel like I need to return anything.

+3


source to share


1 answer


You need to make some changes to your code in order to access the inner

functions person()

. Added return this

at the end person()

so that internal properties and methods person()

can be accessed externally person()

.

See the changes highlighted in the code below.

var SomeClass = function() {
  this.get = function() {
    browser.get('http://blah');
  };

  this.person = function() {
    var firstNameInput = element(by.id('firstName'));
    var lastNameInput = element(by.id('lastName'));

    this.setTitle = function(title) {
      element(by.xpath('//select[@id="title"]/option[text()="' + title + '"]')).click();
    };

    this.setFirstName = function(firstName) {
      firstNameInput.sendKeys(firstName);
    };

    this.setLastName = function(lastName) {
      lastNameInput.sendKeys(lastName);
    };

    return this;
    // ^^^^^^^^^
  };
};

module.exports = new SomeClass();
      

Run code


Then you can access setTitle

as follows.



someClass.person().setTitle(data.title)
//              ^^ 

      

Demo

var SomeClass = function() {
  this.person = function() {
    this.setTitle = function(title) {
      document.write(title);
    };

    return this;
    // ^^^^^^^^^
  };
};

var myObj = new SomeClass();
myObj.person().setTitle('Hello World!');
      

Run code


+2


source







All Articles