Location

Location wraps expo-location's foreground position: a position signal that a one-off current() and a running start() both write to. Nothing is watched until you call one of them, and the accuracy is explicit - GPS at navigation accuracy is a battery the user notices.

Import
import { Location } from '@ng-native/expo';
Inject
inject(Location)

Install

npx expo install expo-location
import { Location } from '@ng-native/expo/location';

The smallest thing that works

import { Component, inject, type OnDestroy } from '@angular/core';
import { Location } from '@ng-native/expo/location';

@Component({
  selector: 'app-run',
  template: `
    @if (location.position(); as here) {
      <text>{{ here.latitude }}, {{ here.longitude }}</text>
    }
  `,
})
export class Run implements OnDestroy {
  protected readonly location = inject(Location);
  private stop = () => {};

  async start(): Promise<void> {
    this.stop = await this.location.start({ accuracy: 'high', distance: 10 });
  }

  ngOnDestroy(): void {
    this.stop();
  }
}

Reading a position

  • position is a signal: null until something has been read, then the latest fix - latitude, longitude, altitude, accuracy, heading, speed and timestamp. altitude, accuracy, heading and speed are null where the platform does not know them.
  • current(accuracy) reads the position once and returns it (or null, without the permission or the module).
  • start({ accuracy, distance, interval }) follows the position into the signal, resolving to the function that stops watching. distance is metres moved before the next update; interval is milliseconds between updates, Android only - iOS updates on distance moved, not on a timer.
  • The accuracy is a name, not Expo's numeric enum: lowest, low, balanced (the default), high, highest or navigation. Worth choosing deliberately: navigation keeps the GPS hot.

Both current() and start() ask for the foreground permission themselves, via location.permission (see Permissions), and do nothing without it - current() resolves to null, start() to a stop function that does nothing. Location in the background is not wrapped by this service; use expo-location's own background API directly if you need it.

Add to Info.plist:

<key>NSLocationWhenInUseUsageDescription</key>
<string>Allow this app to use your location</string>

Android's ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION permissions are added automatically by the module's config plugin.

Without the module

permission reports denied with canAskAgain: false. current() resolves to null and start() to a stop function that does nothing, exactly as though the permission had been refused.

Reference

Locationservice@ng-native/expo
import { Location } from '@ng-native/expo';

Methods

current(accuracy: LocationAccuracy = 'balanced'): Promise<Position | null>

Read the position once. Null without the permission or the module.

start(options: WatchOptions = {}): Promise<() => void>

Follow the position into the signal. Resolves to the function that stops.

Angular components as native iOS and Android views, built and shipped with Expo.

An alpha. MIT licensed. Sponsor its development.

An independent project, not affiliated with or endorsed by Google, the Angular team or Expo. Angular is a trademark of Google LLC.