Flutter Web and Location
Tags: flutter, productivity, javascript, webdev
Published: 2020-04-15 04:42:21

*In case it helped :)*
<a href="https://www.buymeacoffee.com/aseemwangoo" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Pass Me A Coffee!!" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>

<!-- wp:heading {"level":4} -->
<h4>Begin…</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>We will cover two points in this article…</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><li>Detect user’s location using Mozilla Geolocation</li><li>Calling location API for getting location</li></ol>
<!-- /wp:list -->

{% youtube TdMZs9xrRAo %}

<!-- wp:heading {"level":4} -->
<h4>Overview of Mozilla Geolocation…</h4>
<!-- /wp:heading -->

####Article here: https://flatteredwithflutter.com/detect-user-location-in-flutter-web/

<!-- wp:paragraph -->
<p>As per the documentation <a href="https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API" rel="noreferrer noopener" target="_blank">here</a>,</p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>The <strong>Geolocation API</strong> allows the user to provide their location to web applications if they so desire. For privacy reasons, the user is asked for permission to report location information.</p></blockquote>
<!-- /wp:quote -->

<!-- wp:paragraph -->
<p>This api can be accessed by calling <code>navigator.geolocation</code> After calling, it causes the user’s browser to ask them for permission to access their location data</p>
<!-- /wp:paragraph -->

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/5v4wso8u007umgdc62u8.png)

<!-- wp:paragraph -->
<p>After accepting the request, the browser will use the best available functionality on the device to get the location (for example, GPS). Now, we can access the location information via <code>Geolocation.getCurrentPosition()</code></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If the location retrieval is successful, the callback executes with a <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/GeolocationPosition" rel="noreferrer noopener" target="_blank">GeolocationPosition</a></code> object&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:separator -->
<hr class="wp-block-separator"/>
<!-- /wp:separator -->

<!-- wp:heading {"level":4} -->
<h4>Flutter Web and Mozilla Geolocation…</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><em>Time to call javascript from Flutter Web..</em></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>Step 1&nbsp;: Importing JS package..</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Add the following to your <code>pubspec.yaml</code>:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>dependencies:  js: ^0.6.0</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p><strong>Step 2 : (Create the helper file)</strong></p>
<!-- /wp:paragraph -->

<!-- wp:separator -->
<hr class="wp-block-separator"/>
<!-- /wp:separator -->

<!-- wp:paragraph -->
<p>Lets create a separate helper file called <code>loc.dart</code> We know that our geolocation is present inside <code>navigator.geolocation</code> (refer explanation above)..</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>For calling any JS library, we make use of <code>@JS('YOUR LIBRARY')</code> from the<a href="https://pub.dev/packages/js" rel="noreferrer noopener" target="_blank"><strong> js package</strong></a>…</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">@JS('navigator.geolocation')<br>library jslocation; // YOU CAN NAME WHATEVER YOU WANT</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p>Here, <code>navigator.geolocation</code> is the library we want to invoke..The second line, <code>library jslocation</code> (you can name it whatever you want), in my case I named it <code>jslocation</code>&nbsp;…</p>
<!-- /wp:paragraph -->

<!-- wp:separator -->
<hr class="wp-block-separator"/>
<!-- /wp:separator -->

<!-- wp:paragraph -->
<p>Next, we know for accessing geolocation we need to invoke <code>Geolocation.getCurrentPosition()</code> (refer explanation above). For calling <code>getCurrentPosition</code> function, we again make use of <a href="https://pub.dev/packages/js" rel="noreferrer noopener" target="_blank"><strong>js package</strong></a>as</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">@JS('getCurrentPosition') //Geolocation API's getCurrentPosition

external void getCurrentPosition(Function success(GeolocationPosition pos));</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p>In the first line, we invoke the <code>getCurrentPosition.</code> The second line, is the function definition, which gets called from dart side….</p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Note&nbsp;: Try to keep the JS function and the dart function names consistent, in our case it’s <strong>getCurrentPosition</strong></p></blockquote>
<!-- /wp:quote -->

<!-- wp:paragraph -->
<p>Now, the geolocation API returns a callback for success, which we want to capture in dart side, hence we pass in a callback fxn to our dart function…</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">Function success(GeolocationPosition pos)</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p><strong>Step 3&nbsp;: Define the Custom object (GeolocationPosition)</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In order to pass or fetch a custom class from a JS, we need to define it using <code>@JS() and @anonymous</code> tags from <a href="https://pub.dev/packages/js" rel="noreferrer noopener" target="_blank"><strong>js package</strong></a></p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>As per the docs, <strong>@anonymous</strong> is</p></blockquote>
<!-- /wp:quote -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>A metadata annotation that indicates that a @JS annotated class is structural and does not have a known JavaScript prototype.</p></blockquote>
<!-- /wp:quote -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">@JS()
@anonymous
class GeolocationPosition {

  external factory GeolocationPosition({GeolocationCoordinates coords});

external GeolocationCoordinates get coords;
}</pre>
<!-- /wp:preformatted -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>We use factory constructors for our class as they desugar to create JavaScript object literals with name-value pairs…</p></blockquote>
<!-- /wp:quote -->

<!-- wp:paragraph -->
<p>On the similar lines, we create <strong>GeolocationCoordinates,</strong></p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">@JS()
@anonymous
class GeolocationCoordinates {
  external factory GeolocationCoordinates({
    double latitude,
    double longitude,
  });

external double get latitude;
  external double get longitude;
}</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p><strong>Step 4&nbsp;: Final Step (Calling from Dart)</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>We exposed our <code>getCurrentPosition</code> in Step 2, its time to call it now….We need to pass a function as a param to <code>getCurrentPosition..</code>&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In order to pass a Dart function to a JS API, we need to do that using <code>allowInterop</code> or <code>allowInteropCaptureThis</code>.</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">OutlineButton(<br>    onPressed: () {<br>      getCurrentPosition(allowInterop((pos) {<br>         setState(() {<br>           _latitude = pos.coords.latitude;<br>           _longitude = pos.coords.longitude;<br>         });<br>      }));<br>    },<br>    child: const Text('Mozilla GeoLocation'),<br>),</pre>
<!-- /wp:preformatted -->

<!-- wp:heading {"level":4} -->
<h4>Calling API for location….</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>If the above method was too complicated for you, no worries, we got you covered..</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Step 1&nbsp;: Import <a href="https://pub.dev/packages/http#-installing-tab-" rel="noreferrer noopener" target="_blank"><strong>http package</strong></a></p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>dependencies:  http: ^0.12.0+4</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Step 2 : Call Location API</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In our case, we have called,</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted"><a href="https://geolocation-db.com/json/" rel="noreferrer noopener" target="_blank">https://geolocation-db.com/json/</a></pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p>This gives us response as : (Removed values for the demo)</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">{<br>   "country_code":"",<br>   "country_name":"",<br>   "city":"",<br>   "postal":null,<br>   "latitude":1.2931,<br>   "longitude":103.8558,<br>   "IPv4":"119.74.94.182",<br>   "state":""<br>}</pre>
<!-- /wp:preformatted -->

*In case it helped :)*
<a href="https://www.buymeacoffee.com/aseemwangoo" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Pass Me A Coffee!!" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Hosted URL&nbsp;: <a href="https://fir-signin-4477d.firebaseapp.com/#/" rel="noreferrer noopener" target="_blank">https://fir-signin-4477d.firebaseapp.com/#/</a></p></blockquote>
<!-- /wp:quote -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p><a href="https://github.com/AseemWangoo/experiments_with_web" rel="noreferrer noopener" target="_blank">Source code for Flutter Web App..</a></p></blockquote>
<!-- /wp:quote -->

{% youtube TdMZs9xrRAo %}