LocationService API Salesforce LWC

Shama Gurav
5 min readJan 28, 2025

--

LocationService API is provided by salesforce to incorporate location based features in lightning web component in mobile device.

LocationService API is available on mobile devices. This API basically use mobile device’s location feature to determine current location of the device locally on mobile device without network connection. However, it needs access to platform specific API’s which are only available within compatible Salesforce mobile apps.

There are multiple use case where this API can be used and enhance user experience. For example, we can determine users current location and calculate distance between particular landmark.

LocationService API Example:

Following example implements use case to determine users current location and calculate distance between user’s location and selected landmark from list.

I have incorporated google map to show current location of user as well as landmarks.

When user access this component from mobile device, he gets current location dynamically. However, if this component is being accessed from desktop browser then constant geocode location is being used to perform operation to simplify the functionality. Moreover, browser functionality can be improved by saving geocodes of address on user contact and then fetching it in the component.

Mobile view:

Browser view:

Steps to implement the example are as follows:

  1. Create custom object ‘Landmarks’ with following fields,

2. Insert below data in the table.

3. Create Apex controller landmarksController.cls

getLanmarks() method retrive all the landmark from custom object Landmarks__c

calculateDistance() method uses Location class with getDistance() method to calculate distance between two geocodes.

public with sharing class landmarksController {
public landmarksController() {

}

@AuraEnabled(cacheable=true)
public static List<Landmarks__c> getLandmarks() {
return [
SELECT Id, Address__c,Name,Location__c
FROM Landmarks__c
];
}

@AuraEnabled(cacheable=true)
public static Double calculateDistance(String latitude1, String longtitude1, String latitude2, String longtitude2)
{
Location l1 = Location.newInstance(Decimal.valueOf(latitude1), Decimal.valueOf(longtitude1));
Location l2 = Location.newInstance(Decimal.valueOf(latitude2), Decimal.valueOf(longtitude2));
Double distance = Location.getDistance(l1,l2,'km');

return distance;
}
}

4. Create LWC component locationServiceExample.

<!-- locationServiceExample.html -->
<template>

<lightning-card title="Select landmark to check distance from your current location" icon-name="custom:custom63">


<lightning-layout multiple-rows>
<lightning-layout-item size="12" small-device-size="9" padding="around-small">
<lightning-radio-group name="LANDMARKS" label="Radio Group" options={options} value={radvalue}
type="radio" onchange={handleChangeRad}></lightning-radio-group>
</lightning-layout-item>
<lightning-layout-item size="12" small-device-size="9" padding="around-small">


<p class="slds-text-color_success slds-text-align_center">
{varDisstance}
<br/>
Current location is:<lightning-formatted-location latitude={currentLocationToDisplay.lat} longitude={currentLocationToDisplay.long}></lightning-formatted-location>
</p>


</lightning-layout-item>
<!-- Current location as latitude and longitude -->

</lightning-layout>
</lightning-card>


<!-- After the current location is received,
its value is displayed here: -->
<template lwc:if={showMap}>

<div class="slds-m-vertical_large slds-p-vertical_medium
slds-text-align_left slds-border_top slds-border_bottom">


<!-- Current location as a map -->
<lightning-map map-markers={locationMarkerslist} zoom-level=10 center={center} list-view="visible">
</lightning-map>
</div>
</template>


<!-- While request is processing, show spinner -->
<div class="slds-m-around_large">
<template lwc:if={requestInProgress}>
<div class="slds-is-relative">
<lightning-spinner alternative-text="Getting location...">
</lightning-spinner>
</div>
</template>
</div>


</template>
// LocationServiceDemo.js
import { LightningElement, wire, track } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { getLocationService } from 'lightning/mobileCapabilities';
import getLandmarksList from '@salesforce/apex/landmarksController.getLandmarks';
import calculateDistance from '@salesforce/apex/landmarksController.calculateDistance';
export default class LocationServiceDemo extends LightningElement {
dynamicInstance;
// Internal component state
myLocationService;
currentLocation;
locationButtonDisabled = false;
requestInProgress = false;
landmarkList;
@track options = [];
value = [];
radvalue = '';
@track mapIdToLocation = new Map();
@track userlocation;
@track showMap = false;
@track varDisstance;
@track locationMarkerslist = [];

lstLand = [];

// Define the center of the map
center = {
location: {
Latitude: 40.730610, // New york Latitude
Longitude: -73.935242 // New York Longitude
}
};

// Format Location object for use with lightning-map base component
get currentLocationAsMarker() {

if (this.currentLocation != null) {
return [{
location: {
Latitude: this.currentLocation.coords.latitude,
Longitude: this.currentLocation.coords.longitude
},
title: 'My Location'
}]
} else {
return [{
location: {
Latitude: 40.75618,
Longitude: -73.99342
},
title: 'My Location'
}]
}

}


calDistance(lat1, long1, lat2, long2) {
calculateDistance({ latitude1: lat1, longtitude1: long1, latitude2: lat2, longtitude2: long2 }).then(result => {
console.log('Distance:', result);
this.varDisstance = 'Distance from selected landmark ' + result.toFixed(4) + ' km.';
}).catch(error => {

})
}
handleChangeRad(e) {


this.radvalue = e.detail.value;

var testId = this.radvalue;

var lat1 = this.currentLocationAsMarker[0].location.Latitude;
var long1 = this.currentLocationAsMarker[0].location.Longitude;
if (!this.locationButtonDisabled) {
this.handleGetCurrentLocationClick();
}

this.calDistance(lat1, long1, this.mapIdToLocation.get(String(testId)).latitude, this.mapIdToLocation.get(String(testId)).longitude);

}

@wire(getLandmarksList) landmarks({ error, data }) {
if (data) {
this.landmarkList = data;
console.log('Landmark ');
console.log(JSON.stringify(this.locationMarkerslist));
//const mapids=new Map();
this.landmarkList.forEach(lm => {
var land = {
label: lm.Name,
value: lm.Id
}
var loc = {
latitude: lm.Location__c.latitude,
longitude: lm.Location__c.longitude,
Name: lm.Name
}

this.mapIdToLocation.set(lm.Id, loc);

this.options.push(land);
this.locationMarkerslist.push(
{
location: {
Latitude: lm.Location__c.latitude,
Longitude: lm.Location__c.longitude
},
title: lm.Name
}
);

});
this.showMap = true;

} else if (error) {
console.log('error ');
}
};
// When component is initialized, detect whether to enable Location button
connectedCallback() {

this.myLocationService = getLocationService();
if (this.myLocationService == null || !this.myLocationService.isAvailable()) {
this.locationButtonDisabled = true;
}
this.locationMarkerslist = this.currentLocationAsMarker;

}

handleGetCurrentLocationClick(event) {
// Reset current location
this.currentLocation = null;

if (this.myLocationService != null && this.myLocationService.isAvailable()) {

// Configure options for location request
const locationOptions = {
enableHighAccuracy: true
}

// Show an "in progress" spinner before we start the request
this.requestInProgress = true;

// Make the request
// handle results or errors
this.myLocationService
.getCurrentPosition(locationOptions)
.then((result) => {
this.currentLocation = result;

// result is a Location object
console.log(JSON.stringify(result));

this.dispatchEvent(
new ShowToastEvent({
title: 'Location Detected',
message: 'Location determined successfully.',
variant: 'success'
})
);
})
.catch((error) => {

// Inform the user we ran into something unexpected
this.dispatchEvent(
new ShowToastEvent({
title: 'LocationService Error',
message:
'There was a problem locating you: ' +
JSON.stringify(error) +
' Please try again.',
variant: 'error',
mode: 'sticky'
})
);
})
.finally(() => {
console.log('#finally');
// Remove the spinner
this.requestInProgress = false;

});
} else {
// LocationService is not available
// Not running on hardware with GPS, or some other context issue

// Let user know they need to use a mobile phone with a GPS
this.dispatchEvent(
new ShowToastEvent({
title: 'LocationService Is Not Available',
message: 'Try again from the Salesforce app on a mobile device.',
variant: 'error'
})
);
}
}

// Format LocationService result Location object as a simple string
get currentLocationToDisplay() {
if (this.currentLocation != null) {
var curLoc={
lat:this.currentLocation.coords.latitude,
long:this.currentLocation.coords.longitude

}
return curLoc;

} else {

var curLoc={
lat:this.locationMarkerslist[0].location.Latitude,
long:this.locationMarkerslist[0].location.Longitude
}
return curLoc;

}
}


}
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>62.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__Tab</target>
</targets>
</LightningComponentBundle>

5. Go to setup and create new lightning component tab for component LocationServiceDemo

5. Check the result.

Reference:

--

--

No responses yet