Trying to fix the loading of the Google Maps JavaScript API without a callback

Hi.

I have a problem with the Google Map javascript API since it is imposible to load it without a callback.

It is described in this site: How to fix Loading the Google Maps JavaScript API without a callback is not supported

My website – running on Joomla” – loads the GM API using an extensión, and the developer seems to be out the business some time ago.

There is a line in the code that should add the callback. I am not a coder and after some failed attempts I am not sure about the way to do it.

I have these two lines:

$url = 'https://maps.googleapis.com/maps/api/geocode/json?address=' . $address . '&key=' . $this->getServerApiKey();


JHtml::script('https://maps.googleapis.com/maps/api/js?key=' . $this->getJsApiKey());

And the code:

<?php

defined('_JEXEC') or die;

class SiteGoogleMaps
{
    protected $jsApiKey;
    protected $serverApiKey;

    public function __construct($jsApiKey, $serverApiKey)
    {
        $this->jsApiKey = $jsApiKey;
        $this->serverApiKey = $serverApiKey;
    }

    public static function getInstance($jsApiKey, $serverApiKey)
    {
        static $instance = null;

        if (is_null($instance)) {
            $instance = new self($jsApiKey, $serverApiKey);
        }

        return $instance;
    }

    public function getJsApiKey()
    {
        return $this->jsApiKey;
    }

    public function getServerApiKey()
    {
        return $this->serverApiKey;
    }

    public function geoCode($address)
    {
        jimport('joomla.filesyste.file');

        $address = urlencode($address);
        $url = 'https://maps.googleapis.com/maps/api/geocode/json?address=' . $address . '&key=' . $this->getServerApiKey();
        $data = json_decode($this->getUrl($url));

        \Joomla\CMS\Log\Log::add(
            sprintf('Decoding address "%s", using api key "%s" and geocoding url: "%s"', urldecode($address), $this->getServerApiKey(), $url),
            \Joomla\CMS\Log\Log::INFO,
            'com_site.google_maps.geocoding'
        );

        if ('OK' != $data->status || !isset($data->results[0]->geometry->location)) {
            \Joomla\CMS\Log\Log::add(
                sprintf('Decoding address "%s" failed with error "%s"', urldecode($address), $data->error_message),
                \Joomla\CMS\Log\Log::ERROR,
                'com_site.google_maps.geocoding'
            );

            return false;
        }

        $location = $data->results[0]->geometry->location;

        \Joomla\CMS\Log\Log::add(
            sprintf('Decoded address "%s" to latitude "%s" and longitude "%s"', urldecode($address), $location->lat, $location->lng),
            \Joomla\CMS\Log\Log::NOTICE,
            'com_site.google_maps.geocoding'
        );

        return $location;
    }

    public function renderMap($id = 'site-googlemap', $location = array(), $height = '400', $width = '100%', $config = array())
    {
        // Render Javascript.
        FactoryHtml::script('googlemaps');
        JHtml::script('https://maps.googleapis.com/maps/api/js?key=' . $this->getJsApiKey());

        JText::script('JPREVIOUS');
        JText::script('JNEXT');

        // Set default values for location.
        if (!is_array($location)) {
            $location = array();
        }

        if (!isset($location['lat']) || !isset($location['lng'])) {
            $location['lat'] = 48;
            $location['lng'] = 14;
        }

        if (!isset($location['zoom'])) {
            $location['zoom'] = 3;
        }

        // Set default values for dimension.
        if (false === strpos($height, '%')) {
            $height .= 'px';
        }

        if (false === strpos($width, '%')) {
            $width .= 'px';
        }

        $optionUseSimpleMarker = isset($config['useSimpleMarkers']) ? $config['useSimpleMarkers'] : 'false';
        $options = '{ center: new google.maps.LatLng(' . $location['lat'] . ', ' . $location['lng'] . '), zoom: ' . $location['zoom'] . ', useSimpleMarkers: ' . $optionUseSimpleMarker . ' }';

        if ($optionUseSimpleMarker) {
            JHtml::script('components/com_site/assets/js/oms.min.js');
        }

        $document = JFactory::getDocument();
        $initJs = '$("#' . $id . '").siteGoogleMap(' . $options . ') ';
        $js = array();

        $js[] = 'jQuery(document).ready(function ($) { ';

        if (isset($config['initOnTabOpen'])) {
            $tab = $config['initOnTabOpen'];
            $js[] = 'var tab = $(".nav li a[href=\"#' . $tab . '\"]");';
            $js[] = 'if (tab.parent().hasClass("active")) {';
            $js[] = $initJs;
            $js[] = '}';
            $js[] = 'else {';
            $js[] = '  $(".nav li a[href=\"#' . $tab . '\"]").click(function (event) { ';
            $js[] = $initJs;
            $js[] = '  });';
            $js[] = '}';
        } else {
            $js[] = $initJs;
        }

        $js[] = ' });';

        $document->addScriptDeclaration(implode("\n", $js));

        $html = array();

        $html[] = '<div id="' . $id . '" style="height: ' . $height . '; width: ' . $width . ';" class="site-google-map"></div>';

        return implode("\n", $html);
    }

    public function renderJavascript()
    {
        FactoryHtml::script('googlemaps');
        JHtml::script('https://maps.googleapis.com/maps/api/js?key=' . $this->getJsApiKey());
    }

    protected function getUrl($url)
    {
        if (function_exists('curl_init')) {
            $ch = curl_init();

            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

            $output = curl_exec($ch);

            if (!curl_errno($ch)) {
                curl_close($ch);
                return $output;
            }

            curl_close($ch);
        }

        return file_get_contents($url);
    }
}

I am not sure whether it can be fixed by editing the code above or I should replace the extensión.

Thanks for any reply.

So what happens when you do what the page you linked to says, and put the additional parameter into the URL above?

I have edited the code including the callback this way:

$url = 'https://maps.googleapis.com/maps/api/geocode/json?address=' . $address . '&key=' . $this->getServerApiKey() . '&callback=Function.prototype';

And

JHtml::script('https://maps.googleapis.com/maps/api/js?key=' . $this->getJsApiKey() . '&callback=Function.prototype');	

With no result at all. The console shows the same error:

“Google Maps JavaScript API has been loaded directly without a callback. This is not supported and can lead to race conditions and suboptimal performance.”

And this other code error: “Google Maps JavaScript API warning: NoApiKeys”

On the other hand, in trying to add the callback to the php file, I think that it is not so simple as adding the ending to the line (. '&callback=Function.prototype') since that function does not exists in the code. If I am not wrong.

As I said, I am not a coder and have got lost in this case. I do not even know if it is possible to fix the code to get the API working again.

Thanks very much for any reply.