0

It seems the buildGeoLocation() method cannot run this.requestHandler() but I can't seem to work out why.
The console shows Uncaught TypeError: this.requestHandler is not a function.

Below is my code:

class Geolocation {
    constructor() {
        this.elements = {
            section: document.querySelector('.james-section'),
            button: document.querySelector('.james-button'),
        }

        this.elements.button.addEventListener('click', this.buildGeoLocation)
    }

    buildGeoLocation() {
        Promise.all([
            this.requestHandler("https://freegeoip.app/json/"),
            this.requestHandler("geolocation-template.html")
        ]).then(function(values) {
            const data = JSON.parse(values[0]);
            const markup = values[1]
                .replace('[ip]', data.ip)
                .replace('[city]', data.city)
                .replace('[country]', data.country_name)
                .replace('[lat]', data.latitude)
                .replace('[lng]', data.longitude);

            elements.section.innerHTML = markup;
        }).catch(function(reason) {
            console.log(reason);
        });
    }

    requestHandler(url) {
        return new Promise(function(resolve, reject) {
            const xhttp = new XMLHttpRequest();
            xhttp.onreadystatechange = function() {
                if(this.readyState == 4) {
                    if(this.status == 200) {
                        resolve(this.responseText);
                    } else {
                        reject('Call Failed');
                    }   
                }
            };
            xhttp.open("GET", url);
            xhttp.send();
        });
    }
}

new Geolocation;

I'm quite new to using Classes so any pointers would be much appreciated

  • `.addEventListener('click', this.buildGeoLocation)` -> `.addEventListener('click', () => this.buildGeoLocation)` – VLAZ Apr 18 '22 at 12:10
  • `elements.section.innerHTML = markup;` should be `this.elements.section.innerHTML = markup;` and `this.elements.button.addEventListener('click', this.buildGeoLocation)` should be `this.elements.button.addEventListener('click', this.buildGeoLocation.bind(this))` or `this.elements.button.addEventListener('click', () => this.buildGeoLocation())` – epascarello Apr 18 '22 at 12:10
  • Thank you @epascarello – Both solutions worked to preserve the value of `this` when calling the `buildGeoLocation()` function. – jameshalldev Apr 19 '22 at 11:41

0 Answers0