0

March 2021, I have installed ionic as well as the geolocation component.

This is the code in the "home.page.ts":

async getMyLocation1() {
  let watch = await this.geolocation.watchPosition();
  watch.subscribe((data) => {      
    console.log(data.coords.latitude);  
  });
}

The word "coords" underlines it in red and if I put the mouse pointer over it, it tells me the following image:

enter image description here

The getCurrentPosition () function does return it to me without problems but watchPosition () does not achieve anything. I don't know if I used it wrong or what. Can anybody help me?

ljta_69
  • 41
  • 1
  • 3

2 Answers2

0

Reading the library documentation I could read this:

/**
* Watch the current device's position.  Clear the watch by unsubscribing from
* Observable changes.
*
* ...
*
* @param {GeolocationOptions} options  The [geolocation options](https://developer.mozilla.org/en-US/docs/Web/API/PositionOptions).
* @returns {Observable<Geoposition | PositionError>} Returns an Observable that notifies with the [position](https://developer.mozilla.org/en-US/docs/Web/API/Position) of the device, or errors.
*/
watchPosition(options?: GeolocationOptions): Observable<Geoposition | PositionError>;

As you see, the method returns an Observable<Geoposition | PositionError>. So, the error you are getting is because the property Geoposition.coords.latitude exists in a Geoposition interface, but it doesn't exists in a PositionError, so it doesn't exists in a Observable<Geoposition | PositionError>. This is a Typescript error.

You hace two choices then:

  1. Make the data type any, but you will not be checking for PositionError:
async getMyLocation1() {
    let watch = await this.geolocation.watchPosition();
    watch.subscribe((data:any) => {      
        console.log(data.coords.latitude);
    });
}
  1. Change the code to verify if the data accomplish a Geoposition interface (this interface check was inspired by this):
async getMyLocation1() {
    let watch = await this.geolocation.watchPosition();
    watch.subscribe((data:any) => {
        if (this.isGeoposition(data)) {
            console.log(data.coords.latitude);  
        } else {
            console.log('Error getting location');
        }
    });
}

isGeoposition(data: any): data is Geoposition {
    return (data.coords !== undefined && data.timestamp !== undefined);
}

By the way, if you are wondering when would the watchPosition method return a PositionError, one example would be when the browser asks for your location, and you deny the permission it will generate a PositionError instead of a Geoposition.

  • Yes now, thank you. The only thing that happens is that the data values, such as the coordinates, I want to get them out of the function and it can't be done, the values are lost even if you assign them to a global variable, they are only kept inside the subscribe. – ljta_69 Mar 19 '21 at 16:42
  • Could you show me how are you trying to do so? – Enmanuel Rodríguez Paz Mar 19 '21 at 18:07
0

The code that I have in the home.pge.ts, is the following:

import { Component, OnInit } from '@angular/core';
import { Geolocation, Geoposition } from '@ionic-native/geolocation/ngx';

declare var google;

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {

  public datGPS = {
    lat: 0,
    lng: 0,    
  };
  
  constructor(private geolocation: Geolocation){
   
  }


  ngOnInit() {          
    this.loadMap(); 
  }


  async loadMap() {      
    this.getMyLocation();
    console.log("LoadMap: " + this.datGPS.lat);
    console.log("LoadMap: " + this.datGPS.lng);    
  }

  async getMyLocation() {        
    let watch = await this.geolocation.watchPosition();
    watch.subscribe((data:any) => {
        if (this.isGeoposition(data)) {            
            this.datGPS.lat = data.coords.latitude;
            this.datGPS.lng = data.coords.longitude           
            console.log("getMyLocation: " + this.datGPS.lat);
            console.log("getMyLocation: " + this.datGPS.lng);
        } else {
            console.log('Error getting location');
        }
    });
  }

  isGeoposition(data: any): data is Geoposition {
      return (data.coords !== undefined && data.timestamp !== undefined);
  }
}

When I execute it, the "console.log" that is inside the promise in "getMyLocation" have value, for example the "this.datGPS.lat", if it has a value, but the one that I have outside in the "loadMap" function is steel. I imagine that it is because outside the environment of the promise the values do not come out and therefore from there we will have to add the code to show it on the map or / and call a service that saves it in a DB, but all this from within the subscriber's environment.

ljta_69
  • 41
  • 1
  • 3
  • The "await/async" is wrong, the "await" you has no effect in your code because "await" is used with Promises, but "this.geolocation.watchPosition()" returns an Observable. You are mixing two different things. You need to find a way to wait for the subscription to end, or change your code logic – Enmanuel Rodríguez Paz Mar 22 '21 at 12:16