Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to block gmap when there is no internet connection

I'm using the PrimeFaces component gmap, to be able to use Google Maps service. It works fine for me, but I have an issue. When there is no internet connection, my user interface totally get blocked. Is there any way to solve this problem, by not rendering the gmap in case no internet connection? This is my code:

<p:gmap id="geoGmap" widgetVar="geoMap" center="#{managedBean.centerGeoMap}" zoom="15" type="ROADMAP" model="#{managedBean.geoModel}" style="width:1000px;height:500px" streetView="false" disableDefaultUI="true"  >
    <p:ajax event="geocode" listener="#{managedBean.onGeocode}" update="@this" />
</p:gmap>

And here is the script to import it:

<script src="https://maps.google.com/maps/api/js?sensor=false" type="text/javascript" ></script>
like image 599
Bilal Dekar Avatar asked Sep 28 '16 07:09

Bilal Dekar


People also ask

Do you need internet for Google Maps?

Use offline maps After you've downloaded an area, use the Google Maps app just as you normally would. If your Internet connection is slow or absent, your offline maps will guide you to your destination as long as the entire route is within the offline map.

How can I use maps app without internet?

Download Google Maps for offline use To download a map, go to the Google Maps app on your phone– doesn't matter if it's Android or iOS. Now tap on the hamburger menu icon in the top left corner of the screen and tap on 'Offline maps'.

Does GPS work without internet?

GPS tracking on your phone works just as well without internet connectivity or cellular service. We are constantly surrounded by Global Positioning System signals from satellites orbiting the planet. Your phone is continuously tracking these signals to get an estimate of your location even when you are offline.

Why does Google Maps only work with Wi-Fi?

You must enable Data roaming to use a cellular network in a different region than yours. That might also be the reason for Google Maps not working on mobile data. To turn data roaming on iPhone, go to Settings > Mobile data > Mobile data options. Enable the toggle next to Data Roaming.


1 Answers

When there is no internet connection, my user interface totally get blocked

This is caused by a JavaScript error. You can see it when you check the JavaScript console in browser's developer toolset. Press F12 in Chrome/FF23+/IE9+ to see it.

Uncaught ReferenceError: google is not defined

In Chrome, you can unfold a stack trace. When you click the first line, it refers to the script generated by <p:gmap> in HTML source as shown below (whitespace manually inserted for readability):

<script id="geoGmap_s" type="text/javascript">
    $(function() {
        PrimeFaces.cw('GMap', 'geoMap', {
            id: 'geoGmap',
            mapTypeId: google.maps.MapTypeId.ROADMAP, // <-- Here,
            center:new google.maps.LatLng(...),       // <-- and here.
            ...
        });
    });
</script>

Look, this inline script is trying to dereference the variable google which is supposed to be put in the window scope by the Google Maps API JavaScript file. However, when there's no internet connection, then that Google Maps API JavaScript file fails to load and hence there will be no google variable in the window scope and therefore this <p:gmap>-generated script will throw an error saying that the variable google is undefined.

When there's an unhandled error in JavaScript context, then the JavaScript execution will come to a total halt. In other words, the remaining scripts, such as those for other PrimeFaces user interface components whose functionality heavily depend on JavaScript, won't at all be executed. That explains your observation of "my user interface totally get blocked".

Technically, the solution is rather straight forward: the <p:gmap> should not try to execute that script when the variable google is not in the window scope.

In order to achieve that, you need to extend the renderer of <p:gmap>, the GMapRenderer, to write an if (window.google) directly after starting of the script:

public class YourGMapRenderer extends GMapRenderer {

    @Override
    protected void startScript(ResponseWriter writer, String clientId) throws IOException {
        super.startScript(writer, clientId);
        writer.write("if(window.google)");
    }

}

In order to get it to run, register it as below in faces-config.xml where the <renderer-class> represents the FQN of your extended renderer class:

<render-kit>
    <renderer>
        <component-family>org.primefaces.component</component-family>
        <renderer-type>org.primefaces.component.GMapRenderer</renderer-type>
        <renderer-class>com.example.YourGMapRenderer</renderer-class>
    </renderer>
</render-kit>

Once installed, it will change the rendered script as below:

<script id="geoGmap_s" type="text/javascript">
    if (window.google) $(function() {
        PrimeFaces.cw('GMap', 'geoMap', {
            ...
        });
    });
</script>

In other words, the function will only be invoked when window.google is truthy, i.e. when the google variable is available in JavaScript's window scope.

That should avoid the JS error and let the JS execution continue.

like image 185
BalusC Avatar answered Oct 30 '22 05:10

BalusC