-1

As i want to use location information in my Ionic 5/Capacitor app, i wrote a first version of a wrapper around the Geolocation API.

The issue is, that when i inject this service and call startReceivingLocationUpdates() i get the following error:

core.js:6014 ERROR TypeError: Cannot read property 'locationSubject' of undefined
    at locationCallback (location.service.ts:51)
    at window.navigator.geolocation.watchPosition.Object.enableHighAccuracy (geolocation.js:30)
    at ZoneDelegate.invoke (zone-evergreen.js:359)
    at Object.onInvoke (core.js:39699)
    at ZoneDelegate.invoke (zone-evergreen.js:358)
    at Zone.runGuarded (zone-evergreen.js:134)
    at zone-evergreen.js:118

My location service


    import { Injectable } from '@angular/core';
    import { Geolocation, GeolocationOptions, GeolocationPosition } from '@capacitor/core';
    import { BehaviorSubject, Observable } from 'rxjs';

    const locationOptions: GeolocationOptions = {
      enableHighAccuracy: true,
      requireAltitude: false
    };

    @Injectable({
      providedIn: 'root'
    })
    export class LocationService {

      private locationSubject = new BehaviorSubject<GeolocationPosition>(null);

      private watchId: string = null;

      constructor() {
      }

      receivingLocationUpdates(): boolean {
        return this.watchId != null;
      }

      startReceivingLocationUpdates()
      {
        if(this.watchId !== null)
          return;

        this.watchId = Geolocation.watchPosition(locationOptions, this.locationCallback);
      }

      stopReceivingLocationUpdates()
      {
        if(this.watchId === null)
          return;

        Geolocation.clearWatch({id: this.watchId })
          .then(_ => {
            this.watchId = null;
          });
      }

      subscribe(): Observable<GeolocationPosition>
      {
        return this.locationSubject.asObservable();
      }

      private locationCallback(location: GeolocationPosition) {
        this.locationSubject.next(location);
      }
    }

What am i doing wrong?

4

1 回答 1

2

The issue here is likely that you are losing what 'this' is pointing at, since the callback function (locationCallBack) gets executed within different scope than your class.

To fix this you should either bind the execution scope or make this transparent.

Try using fat arrow function:

  private locationCallback = (location: GeolocationPosition) => {
    this.locationSubject.next(location);
  }

Alternatively you can:

  • pass your class's 'this' scope
  • bind 'this' using .bind(this) approach
于 2020-02-21T00:31:41.620 回答