Jake Wilson
Jake Wilson

Reputation: 91193

Access `this` from within required object literal?

I desire to have the following type of object:

const Client = require('./Client')
let client = new Client()

client.someObject.create(...)
client.someObject.update(...)
client.someObject.delete(...)
etc.

This is very easy to accomplish doing something like this:

const Client = function () {
  this.someObject = {}
  this.someObject.create = function () {...}
  this.someObject.update = function () {...}
  this.someObject.delete = function () {...}
}
module.exports = Client

But from an organizational standpoint (and because of the massive number of functions someObject has, it would be helpful to put all the someObject stuff into it's own file and require it: require('./someObject'). However, I still need to be able to access the Client object (this) within someObject.create(), someObject.update(), etc.

this.someObject = require('./someObject')

// someObject.js
module.exports = {
  create: function () {
    // How do I access Client here? Can I pass it to the object literal?
  }
}

I've tried to do some prototype sub module type of setup but it doesn't appear to work.

Client.prototype.someObject.create = function () { ... }

How can I separate someObject into it's own file and still access the Client this?

Upvotes: 3

Views: 53

Answers (1)

Jonathan Lonowski
Jonathan Lonowski

Reputation: 123473

You'll need to provide the Client instance to someObject itself so the latter's methods can use it to reference the former.

One way you accomplish that is to define a 2nd constructor for someObject that takes the client as an argument.

const SomeObject = function (client) {
  if (!client) throw new Error('Client reference is required.');
  this.client = client;
};

SomeObject.prototype.create = function () {
  let client = this.client;
  // ...
};

// ....

module.exports = SomeObject;
const SomeObject = require('./someObject');

const Client = function () {
  this.someObject = new SomeObject(this);
}

You can also get a similar result with Object.create() if you'd rather keep the object literal:

const baseline = {
  create: function () {
    let client = this.client;
    // ...
  },

  // ...
};

module.exports = function createSomeObject(client) {
  return Object.create(baseline, {
    client: {
      value: client
    }
  });
};
const createSomeObject = require('./someObject');

const Client = function () {
  this.someObject = createSomeObject(this);
};

Upvotes: 1

Related Questions