0

I understand prototypical inheritance, (i.e: if the property is not defined on current object then the prototype chain is traversed until the property or function is found and then it is executed or null is returned).

The problem is that I am getting "undefined" for a property when it should defined. This property is called _context.

Below is the output of Chrome's inspector console. It clearly shows that _context is defined on the prototype of YouAreConnected. (near the bottom)

enter image description here

However my Jasmine test is failing because it says that _context is not defined in the implementation.

enter image description here

Below is the implementation.

define(['voice/states-new/State'],
function(State){

  var YouAreConnected = function YouAreConnected(context){

    Object.setPrototypeOf(this,new State());

    if(!context){
        throw Error('context must be set.');
    }
    else{
        this.__proto__._context = context;
    }

    /**
     * Initializes this state.
     *
     * pre:
     * - _context must be set with a socket connection
     *   which is 'connected'.
     *
     * post:
     * - Any initialization involving the server is
     *   executed.
     */
    this.init = function(){

      console.log(this);   // this produced the chrome console output.

      this._context.socket.emit('createRoom',_context.userId);
    }
  }

  return YouAreConnected;

});

Below is the Jasmine test case.

  it('emits a "createRoom" event to the server upon creation', ()=>{
      var _context = TestHelper.mockContext;
      var state = new YouAreConnected(_context);
      spyOn(_context.socket,'emit');
      state.init();
      expect(_context.socket.emit).toHaveBeenCalled();
  })

UPDATE 1 It seems when I pass a string instead of an object into the YouAreConnected constructor the _context is no longer undefined.

This fails

it('emits a "createRoom" event to the server upon creation', ()=>{
      //var _context = TestHelper.mockContext;
      var state = new YouAreConnected({});  // object passed
      spyOn(_context.socket,'emit');
      state.init();
      expect(_context.socket.emit).toHaveBeenCalled();
  })

This works (_context is no longer undefined)

it('emits a "createRoom" event to the server upon creation', ()=>{
      //var _context = TestHelper.mockContext;
      var state = new YouAreConnected("mock");  // string passed
      spyOn(_context.socket,'emit');
      state.init();
      expect(_context.socket.emit).toHaveBeenCalled();
  })

UPDATE 2

It works (does not show _context undefined here).

  it('emits a "createRoom" event to the server upon creation', ()=>{

      var _context = {

      }
      var state = new YouAreConnected(_context);
      state.init();
  })

However when I add the 'socket' property to the mock object, it again says _context is not defined. I do not understand why.

  it('emits a "createRoom" event to the server upon creation', () => {
      var _context = {
        socket:{

        }
      }
      var state = new YouAreConnected(_context);
      state.init();
  })
kiwicomb123
  • 1,503
  • 21
  • 26
  • 1
    do not use \_\_proto__, ever, use setprototypeof , https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf – mpm Sep 08 '18 at 23:50
  • Possible duplicate of [How does JavaScript .prototype work?](https://stackoverflow.com/questions/572897/how-does-javascript-prototype-work) – mpm Sep 08 '18 at 23:53
  • I refined the question. The _context property is defined on the prototype yet it is still not being found. – kiwicomb123 Sep 09 '18 at 00:52
  • You don't need to put _context on the prototype, why are you trying to do that at first place? just make it a property of YouAreConnected, just write this._context = context – mpm Sep 09 '18 at 01:14
  • You are correct mpm. But, it should work either way because of prototypical inheritance. I did try what you suggested and same failure occurs. – kiwicomb123 Sep 09 '18 at 01:16
  • I've tried stepping through the code in the Chrome debugger and it clearly shows that _context is there. Yet it still says it is 'undefined' when it the thread passes over that line of code. Chrome bug maybe? – kiwicomb123 Sep 09 '18 at 01:49

1 Answers1

0

You are calling:

this._context.socket.emit('createRoom',_context.userId),

But the _context argument in emit is not a local variable so you need to use:

this._context.userId

for that argument. i.e:

this._context.socket.emit('createRoom',this._context.userId),

Also, you never set userId on the _context, but that's a different problem.

kiwicomb123
  • 1,503
  • 21
  • 26