1

I'm trying to apply some OO design patterns to an existing script, and after following some guides on Mozilla's help center, I'm still getting an error when attempting to instantiate the object.

I've looked at these resources for help, but maybe I'm not fully understanding the JavaScript syntax.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript

Error:

Uncaught TypeError: GeoLocMap is not a constructor

The line of the error:

var GeoLocMap = new GeoLocMap();

Should each of the methods below be defined as a prototype?

Thanks for the help!

Code:

function GeoLocMap() {

        this.map = -1;
        this.regionName = "";
        this.options = -1;
        this.openCountData = -1;
        this.chart = -1;

        this.getMap = function () {
            if (this.map == -1) {
                this.map = new google.maps.Map(document.getElementById('geochart-colors'), {
                    zoom: 6,
                    //TODO replace with the region retrieved from eventData
                    center: new google.maps.LatLng(lat, long),
                    mapTypeId: google.maps.MapTypeId.ROADMAP
                });
            } else {
                return this.map;
            }
        };

        this.getMapWidth = function () {
            var docBody = document.body;
            var docElem = document.documentElement;

            if (typeof document.width !== 'undefined') {
                return document.width;// For webkit browsers
            } else {
                return Math.max(docBody.scrollWidth, docBody.offsetWidth, docElem.clientWidth, docElem.scrollWidth, docElem.offsetWidth);
            }
        };

        this.getMapHeight = function () {
            var docBody = document.body;
            var docElem = document.documentElement;

            if (typeof document.height !== 'undefined') {
                return document.height;// For webkit browsers
            } else {
                return Math.max(docBody.scrollHeight, docBody.offsetHeight, docElem.clientHeight, docElem.scrollHeight, docElem.offsetHeight);
            }

        };

        this.getChart = function() {

            if (this.chart == -1){
                this.chart = new google.visualization.GeoChart(document.getElementById('geochart-colors'));
            }

            return this.chart;

        };

        this.getOpenCountData = function () {

            if (this.openCountData == -1) {
                var data = new google.visualization.DataTable();
                data.addColumn('string', 'Country');
                data.addColumn('number', 'Open Count');

                this.openCountData = data;

            }

            return this.openCountData;
        };

        this.addOpenCountDataRow = function(dataRow) {

          if (this.openCountData == -1){
              this.getOpenCountData();
          }

          if (dataRow == -1){
              return -1;
          }

            this.openCountData.addRows(dataRow);

          return 1;

        };

        this.getOptions = function () {

            if (this.options == -1) {
                this.options = {
                    width: width,
                    height: height,
                    region: 'US',
                    resolution: 'provinces',
                    colors: ['#FFFFFF', '#FFFFFF']
                };
            }

            return this.options;
        };

        this.setOptions = function (property, value) {

            if (this.options == -1) {
                this.getOptions();
            }

            if (value === undefined) {
                return -1;
            }

            this.options[property] = value;

            return 1;

        };

        this.drawMap = function() {

            if (this.chart == -1){
                this.getChart();
            }

            if (this.options == -1){
                this.getOptions();
            }

            if (this.openCountData == -1){
                this.getOpenCountData();
            }

            this.chart.draw(this.openCountData, this.options);
        };

    }
Colby
  • 313
  • 4
  • 13
  • 1
    `var GeoLocMap = new GeoLocMap();`? Both same name? – Aᴍɪʀ Jan 03 '17 at 19:18
  • The problem is you are reassigning the value of `GeoLocMap` on that line. So the function `GeoLocMap` will no longer work and be that instance instead, you need to use a different variable name. – Spencer Wieczorek Jan 03 '17 at 19:21

2 Answers2

7

When you do

var GeoLocMap = new GeoLocMap();

you really do

var GeoLocMap = undefined; // hoisted to the top of the scope
// other code in the same scope
GeoLocMap = new GeoLocMap();

hence your error.

Just use a different name, for example

var geoLocMap = new GeoLocMap();

More info in the MDN on variable scope and hoisting

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
-1

You should be aware of JavaScript Hoisting what @Denys Séguret just described is what is happening.

You should assign the new instance to a different variable

var GeoLocMapInstance = new GeoLocMap();
H. J. Rhenals
  • 135
  • 3
  • 7
  • 2
    Is it necessary to make an answer saying that mine is correct ? – Denys Séguret Jan 03 '17 at 19:23
  • 1
    Your answer do not provide context of why is this happening, mine just add the Hoisting definition, you can easy update yours, and I'll remove mine :) , since understanding why the things happens is more important of just say copy/paste code. – H. J. Rhenals Jan 03 '17 at 19:26
  • lol the downvotes, the fact that you also didn't pointed a solution out makes your answer wrong no need to down vote my answer – H. J. Rhenals Jan 03 '17 at 19:28