Kim Kar
Kim Kar

Reputation: 3

How to access 'this' within required module?

I'm trying to make a module that serves as an API wrapper for a certain site. For organizational purposes, there's a central file with the API class that runs some logic in the constructor and requires the files housing the functions for interacting with the API, separated in different files based on category in the lib directory.

[API.js]

const Search = require('./lib/search'),
    Character = require('./lib/character')
    ...

class API {
    constructor(apikey, options = {}) {
        /* some logic... */

        this.endpoint = 'https://some.site/'
        this.globalQueries = {
            key: apikey,
            language: options.lang || 'en',
            ...
        }

        this.search = new Search()
        this.character = new Character()
        ...
    }
}

module.exports = API

What I want to do is have access to the this from this scope in all the required files (probably not the proper wording) so that if, for example, the contents of ./lib/character are

[lib/character.js]

const request = require('request-promise-native')

class Character {
    constructor() {}

    look(name, params = {}) {
        request({
            uri: this.endpoint + 'character/look',
            qs: Object.assign(this.globalQueries, params),
            json: true
        }).then((res) => {
            ...
    }
}

module.exports = Character

then not only will all references to this.endpoint and this.globalQueries work properly, but any other elements in the API.js this will too, as well as being sure that the values are retrieved at call time for each of the functions, so that it's up-to-date with any changes.

I'm at a loss for how to make this work, so any help would be appreciated.

Upvotes: 0

Views: 39

Answers (2)

duc mai
duc mai

Reputation: 1422

Personally I think it is better to specify your needs for Character and Search in the constructors so it is more clear and easy to follow. So it can look like that

class API {
    constructor(apikey, options = {}) {
        /* some logic... */
        const context = {
            endpoint: 'https://some.site/',
            globalQueries: {
                key: apikey,
                language: options.lang || 'en',
            },
        }
        this.context = context;

        this.search = new Search(context)
        this.character = new Character(context)
    }
}

class Character {
    constructor (context) {
      this.context = context
    }

    look (name, params = {}) {
      request({
        uri: this.context.endpoint,
        qs: Object.assign(this.context.globalQueries, params),
        json: true
      })
    }
  }

So the context object is to be shared between parents and their children

Upvotes: 0

djfdev
djfdev

Reputation: 6037

You could pass the parent instance to each of the constructors as an argument, like so:

class Character {
  constructor (parent) {
    this.parent = parent
  }

  look (name, params = {}) {
    request({
      uri: this.parent.endpoint,
      qs: Object.assign(this.parent.globalQueries, params),
      json: true
    })
  }
}

Then, in the API class definition:

class API {
  constructor(apikey, options = {}) {
    /* some logic... */

    this.endpoint = 'https://some.site/'
    this.globalQueries = {
      key: apikey,
      language: options.lang || 'en',
      ...
    }

    this.search = new Search(this)
    this.character = new Character(this)
    ...
  }
}

Upvotes: 1

Related Questions