Vue Native Geolocation (Part two)

Phone showing map of a location in London, UK
Photo by Henry Perks on Unsplash

We’ve got a basic starting app set up in Part One and so now in Part Two we’ll create user location detection using the Vue Native geolocation API for mobile devices.

Privacy laws, either platform or legal requirements, demand that a user provide permission to allow an app obtain the user’s location. The geolocation API has built-in methods to handle the authorization flow.

The current Device API example in the Vue Native docs does not function as expected so we need to modify the code. The result will be a text display of the user location.

Template

The output needs to be wrapped in a template and a container gives us somewhere to put stuff. Views are used for content display and <view>’s may be embedded in other views.

Here we have a button implemented with the <touchable-opacity> Vue Native basic button component. “on-press” calls the “getLocation” method. The “{{ location }}” is the placeholder for the location data. For now, we’ll output all the data returned in “coords” from the “getLocation” method.

The “errorMessage” placeholder is fairly obvious.

<template>
  <view class="container">
    <touchable-opacity :on-press="getLocation">
      <text class="text-field-title">Get Location</text>
    </touchable-opacity>
    <text class="text-field-title">Location:</text>
    <text>{{ location }}</text>
    <text class="text-error">{{ errorMessage }}</text>
  </view>
</template>

Script

To start we need a couple of modules from Expo: Location and Permissions.

The “getLocation” method is the core logic.

For now, the data function returns two values: location which will have all the data from detecting the user location which will include lat, lng, altitude plus more. Then there is a placeholder for error messages.

There are a number of permissions required from a user such as camera or accelerometer access, and, of course, location which may be derived from device gps or other methods such as wifi location.

So, the Permissions API requires a specific argument that the user agrees to share. The API will display a dialog to the user allowing “always”, “when using app” and “deny”. Fairly self evident but there is a condition that we will address later where the user has globally denied access in the device settings.

Upon “allow” the code executes “getCurrentPositionAsync” and this obviously gets the user location. The actual data returned is an object named “coords” which is accessed by dot notation and then assigned to “location” that is displayed on the device screen.

<script>
import * as Location from "expo-location";
import * as Permissions from "expo-permissions";

export default {
  data: function() {
    return {
      location: "",
      errorMessage: ""
    };
  },
  methods: {
    getLocation: function() {
      Permissions.askAsync(Permissions.LOCATION)
        .then(status => {
          if (!status.granted) {
            this.errorMessage = "Permission to access location was denied";
          } else if (status.granted) {
            Location.getCurrentPositionAsync({}).then(location1 => {
              this.location = location1.coords;
              this.errorMessage = "";
            });
          }
        })
        .catch(err => {
          console.log(err);
        });
    }
  }
};
</script>

Style

Pretty standard styling but one thing to note when referring to Expo or React Native documentation is that Vue Native requires Hyphen-case or PasCalCase for style properties and names as well as in the script section for component names and other definitions.

<style>
.container {
  background-color: white;
  align-items: center;
  justify-content: center;
  flex: 1;
}
.text-field-title {
  color: blue;
  font-size: 18;
  margin: 10;
}
.text-error {
  color: red;
}
</style>

Result

Tadaa! Output to the screen is lat/lng in decimal degrees, altitude in meters, some accuracy data, and speed and direction if moving. Each of these parameters may be individually accessed by dot notation such as:

this.lng = location.coords.longitude

Note the ‘this’ which has to refer to a data parameter of “lng”. “{{ lng }}” can then be used to output to the device screen.

Next

In the next Tech Note, we’ll look at passing the location data as a prop to a map component to show user’s location on a map.

Vue Native Geolocation (Part One)

Photo of map centered on Colorado
Photo by Katie Drazdauskaite on Unsplash

This Tech Note describes how to enable geolocation functionality in Vue Native (mobile) apps.

This first post deals with configuring Vue Native applications. The second post will show how to implement user location detection and display of position.

Vue Native

First, what is Vue Native? It’s a framework for developing native mobile apps for IOS and Android platforms. It is a wrapper around React Native API’s. Sometimes, this wrapper can get rather thin and underlying code bleeds through to the development task particularly with rather unhelpful error messaging. However, using the Expo.io framework, a lot of effort is abstracted away. But most of the React Native functionality is still directly available with some syntax changes.

Geolocation is obviously important to many applications but particularly for serving information to users such as nearest places of interest or address finding and routing.

Short Form Setup

Setting up a vue native app is quite straightforward. It requires recent versions of node.js & npm to enable a CLI (command line interface) install.

Requirements:

  • Globally installed node >= 6.0
  • Globally installed npm >= 4.0
  • Globally installed Expo CLI

We’re going to use the Expo CLI.

npm install --global expo-cli

Create New Project

We’ll target the ios platform which will provide us an ios simulator (which should auto-launch) as well as physical device handling by scanning a QR code. Android is similar. This will display a basic app to prove everything is running. The following instructions will create the app and install dependencies.

$ vue-native init geoDemo
$ cd geoDemo
$ npm run ios

Anatomy

Vue Native follows a similar structure to web Vue applications. The following illustrates the required Hello World app.

  • Template (views)
  • Script (javascript)
  • Style (obvious)

Replace the content of App.vue with the following:

Template

Each app requires a template and here we are using a container to provide an entity for component styling. The double {{ }} is moustache syntax for interpolation.

<template>
  <view class="container">
    <text class="text-color-primary">{{message}}</text>
  </view>
</template>

Javascript

Similar to web Vue, there is a data function that returns the message content. In this static example, the data is fixed but it does have to be returned from a data function. Note the value of the ‘key’ which is used in the template interpolation inside the ‘moustache’ double curly braces and is replaced by the assigned value.

<script>
export default {
  data: function() {
    return {
      message: "Hello World"
    };
  }
};
</script>

Style

What’s there to say?

<style>
.container {
  flex: 1;
  background-color: white;
  align-items: center;
  justify-content: center;
}
.text-color-primary {
  color: blue;
  font-size: 30;
}
</style>

The second part of this TechNote will code the user location.