Search code examples
javascriptnode.jsprototype

Calling prototype method inside another results in 'is not a function'


Not sure what I'm doing wrong here because I've had this pattern work fine before.

Getting this error when trying to run the following code:

this.getSpotifyApi is not a function

Not sure why it's losing this scope. Here is the beginning of the object definition:

const logger = require('logger');
const SpotifyApiNode = require('spotify-web-api-node');

module.exports = SpotifyApi;

function SpotifyApi(userRefreshToken) {
    this.refreshToken = userRefreshToken;
    this.initializeApi()
        .then(() => logger.debug('api object initialized'));
};

/**
 * initialize api object
 */
SpotifyApi.prototype.initializeApi = () => {
    let self = this;
    logger.info(this.refreshToken);
    this.getSpotifyApi(this.refreshToken)
        .then((api) => {
            self.api = api;
        });
};

/**
 * get a spotify api wrapper object 
 */
SpotifyApi.prototype.getSpotifyApi = (userToken) => {
    if (userToken)
        return this.getUserTokenApi(userToken);

    return this.getServerTokenApi();
};

From my testing, it seems to always work when the this.function call is the first one to be called after object instantiation but the second always fails. Not sure what I'm doing different in this case to cause this problem.


Solution

  • An arrow function binds the this of the context it is defined in to that function. So if you create an instance from SpotifyApi and call initializeApi on that, then the this in the initializeApi is not that instance of the object, but some other object.

    Change the arrow function to a regular function and it will work:

    SpotifyApi.prototype.initializeApi = function() {
        let self = this;
        logger.info(this.refreshToken);
        this.getSpotifyApi(this.refreshToken)
            .then((api) => {
                self.api = api;
            });
    };
    

    Do the same for all other functions your assign to SpotifyApi.prototype