Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Geolocation with typescript

I have the following code snippet:

pos:number;

getPosition() {
    navigator.geolocation.getCurrentPosition((position) => {

        this.pos = position.coords.latitude;

when I debug I get undefined on this.pos, and some number on position.coords.latitude

But when I have the following code snippet:

pos:any;

getPosition() {
    navigator.geolocation.getCurrentPosition((position) => {

        this.pos = position.coords.latitude;

then the this.pos is set. Why such a behaviour ?

like image 808
adam nowak Avatar asked Nov 09 '22 15:11

adam nowak


1 Answers

If you are sure position is defined and you are getting in there then it's because the this has changed. The this context can change depending on how it's called. If you are calling it through an event then the this will be scoped the the window or the element originating the event. Example

export class GeoService {
  public pos: any;

  public getPosition() {
    navigator.geolocation.getCurrentPosition((position) => {
      this.pos = position;
    });
  }
}

let geo = new GeoService();

// When called, `this` will be the window
setTimeout(geo.getPosition, 1000);

// When called, `this` will be the dom element
document.getElementById('myDiv').addEventListener('click', geo.getPosition);

You can get around this by using an anonymous function that calls the original objects method-

// When called, `this` will be the window
setTimeout(() => { geo.getPosition(); }, 1000);

// When called, `this` will be the dom element
document.getElementById('myDiv').addEventListener('click', () => { geo.getPosition(); });

Or, by setting getPosition as a property of the GeoService class using a lambda to ensure it's scoped properly.

export class GeoService {
  public pos: any;

  public getPosition = () => {
    navigator.geolocation.getCurrentPosition((position) => {
      this.pos = position;
    });
  }
}

Caveats to the latter. It can make things simpler and reduce redundant code but keep in mind that this creates a new function each time the GeoService class is constructed. This means each instance will have a copy of this function, instead of sharing a common memory space. In other words, it's more costly on memory.

Hopefully this solves your problem.

like image 179
micah Avatar answered Nov 15 '22 12:11

micah