3

I am trying to find an easy way to call parent function from child one. However, couldn't really found a way to directly call it from child instance as like in other programming languages.

class ExchangeHandler {
    constructor(getMarketsUrl, getMarketDataBaseUrl, interval) {
        this.interval = interval;
        this.getMarketsUrl = getMarketDataBaseUrl;
        this.getMarketDataBaseUrl = getMarketDataBaseUrl;
    }

    getMarketsUrl() {
        return this.getMarketsUrl;
    }

    getMarketDataBaseUrl() {
        return this.getMarketDataBaseUrl;
    }

    buildQueryUrl(params) {
        return querystring.stringify(params);
    }

    getIntervalParam() {
        return config.intervalToExchangeInput[[config.exchange]][[this.interval]];
    }
}

class BittrexHandler extends ExchangeHandler {
    constructor(interval) {
        super("https://bittrex.com/api/v1.1/public/getmarkets", 
                "https://bittrex.com/Api/v2.0/pub/market/GetTicks", 
                interval);
    }

    buildGetMarketTickerUrl(symbol) {
        return super.getMarketDataBaseUrl() + "?"
                + super.buildQueryUrl({marketName: this.buildSymbolParam(symbol),
                                    tickInterval: super.getIntervalParam()})
    }

    buildSymbolParam(symbol) {
        return "BTC-" + symbol;
    }
}

var bittrexHandler = ExchangeHandlerFactory.getExchangeHandler("bittrex", "hour");
console.log("getMarketsUrl: " + bittrexHandler.getMarketsUrl());

And I get

TypeError: bittrexHandler.getMarketsUrl is not a function

Isn't this possible in javascript? Thanks a lot!

quartaela
  • 2,579
  • 16
  • 63
  • 99

1 Answers1

7

You can't have a data property and a method with the same name as you do with getMarketsUrl. They occupy the same property slot on the object. Change the name of one of them.

When you're trying to execute the method, the interpreter is finding the data property first and thus you can't call the method in the normal way.


In addition, you should not be using super to just call a non-overriden method on the object. For example, change this:

buildGetMarketTickerUrl(symbol) {
    return super.getMarketDataBaseUrl() + "?"
            + super.buildQueryUrl({marketName: this.buildSymbolParam(symbol),
                                tickInterval: super.getIntervalParam()})
}

to this:

buildGetMarketTickerUrl(symbol) {
    return this.getMarketDataBaseUrl() + "?"
            + this.buildQueryUrl({marketName: this.buildSymbolParam(symbol),
                                tickInterval: this.getIntervalParam()})
}
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Maybe the OP should use a getter method? – evolutionxbox Apr 15 '18 at 23:44
  • @evolutionxbox - I think the data property `getMarketsUrl` just needs a different name. Even if they used a getter, the storage location for that value would still need a different name. – jfriend00 Apr 15 '18 at 23:55
  • 1
    Indeed. Common practice is to prepend the property name with an underscore to denote a “private” variable. – evolutionxbox Apr 15 '18 at 23:56
  • @evolutionxbox - Yes, that would be one way to do it. – jfriend00 Apr 15 '18 at 23:57
  • @jfriend00 thanks as you said I changed the variable name and also replaced `super` keywords with `this` and it worked. – quartaela Apr 16 '18 at 00:02
  • @evolutionxbox I prepended as you recommended. But that doesn't really makes it private in js right? – quartaela Apr 16 '18 at 00:03
  • 1
    @quartaela - Javascript doesn't directly support private member variables as a keyword feature. Adding an underscore does not actually make it private. That's just a convention. Private properties can be achieved using the constructor as a closure such as shown here [How to set javascript private variables in constructor](https://stackoverflow.com/questions/6799103/how-to-set-javascript-private-variables-in-constructor/6799116#6799116). But, this requires defining any methods that want to access this property inside your constructor (not using ES6 class syntax). – jfriend00 Apr 16 '18 at 00:06