2

I'm trying to take a more OOP approach to the way I write Javascript. As a relative beginner, I'm a bit confused by the error I'm getting Uncaught TypeError: this.getCoinSelOption is not a function at getBTC. I have the this keyword calling other methods in my class, but it does not want to call a different method on an interval. What should I do here?

How I'm calling:

coins.getBTC(abbr)
setInterval(coins.getBTC, 10000)

I can call the method initially, but when I need to redetermine the abbreviation of the BitCoin, I go to the global const abbr and update the value based on what's selected through the select tag

class Coins {
    constructor () {
        this.coinOptions = document.getElementById('coinOptions');
    }
    getCoinObjects (url) {
        let promise = new Promise((resolve, reject) => {
           fetch(url)
            .then(response => {
                resolve(response.json().then(data => {
                    let coins = []
                    for (var key in data.Data) {
                        coins.push(data.Data[key])
                    }
                    //this is working here!
                    this.getCoinOptions(coins)
                    return coins
                }))
            })
            .catch(response => {
               reject('“Api call failed!”')
            })
          })
        .then(response => {
            return coins
        })
        .catch(response => {
            console.log('error: ' + response)
        })
    }

    getCoinOptions(keys) {
        for (var i = 0; i < keys.length; i++) {
            var opt = document.createElement('option');
            opt.value = keys[i].Symbol
            opt.innerHTML = keys[i].CoinName
            this.coinOptions.appendChild(opt)
        }
    }

    getBTC(abbr) {
        if (abbr === undefined) {
            //this not working here
            abbr = this.getCoinSelOption(this.coinOptions)
            console.log('this is the abbr' + abbr)
        }

        axios.get('https://min-api.cryptocompare.com/data/pricemulti?fsyms='+abbr+'&tsyms=USD')
            .then(res => {
                console.log(abbr)
                const cryptos = res.data[abbr].USD
                price.innerHTML = '$'+cryptos.toLocaleString('en')

                if (targetPrice.innerHTML != '' && targetPriceVal < res.data[abbr].USD) {
                    const myNotification = new window.Notification(notification.title, notification)
                }
                return abbr
            })
        setTimeout(this.getBTC, 10000)
    }

    getCoinSelOption(sel) {
        console.log('called')
        loadBounce.classList.add('loading')
        this.getBTC(sel.options[sel.selectedIndex].value)
        setTimeout(function() {
            loadBounce.classList.remove('loading')
        }, 900)
        return sel.options[sel.selectedIndex].value
    }

}
Sean Kelly
  • 901
  • 7
  • 27
  • 1
    when you pass a function directly as a setInterval argument like that, it loses context. You should either wrap it in an anonymous function or explicitly bind it like `setInterval(coins.getBTC.bind(coins), 10000)` – Hamms Dec 12 '17 at 02:29

0 Answers0