1

For my Angular Project, I generated a geolocation component and want to repeat a function findMe() to show the current location.

Part of code in the component.ts is given as below.

...
export class GeolocationComponent implements OnInit{
 @ViewChild('gmap') gmapElement: any;
 map: google.maps.Map;
 isTracking = false;
 marker: google.maps.Marker;

 constructor(public globalvar: GlobalvarService) { }

 ngOnInit() {
   var mapProp = {
     center: new google.maps.LatLng(-27.542211, 153.1226333),
     zoom: 15,
     mapTypeId: google.maps.MapTypeId.ROADMAP
   };
   this.map = new google.maps.Map(this.gmapElement.nativeElement, mapProp);

   setInterval(this.findMe(), 3000);

 }

 findMe() {
   if (navigator.geolocation) {
     navigator.geolocation.getCurrentPosition((position) => {
       this.showPosition(position);
       console.log("find me");
     });
   } else {
     alert("Geolocation is not supported by this browser.");
   }
 }

 showPosition(position) {
   this.globalvar.latitude = position.coords.latitude;
   this.globalvar.longitude = position.coords.longitude;

   let location = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
   this.map.panTo(location);

   if (!this.marker) {
     this.marker = new google.maps.Marker({
       position: location,
       map: this.map,
       title: 'Got you!'
     });
   }
   else {
     this.marker.setPosition(location);
   }
 }
 ...

In

ngOnInit(), 

I use

setInterval(this.findMe(), 3000);

By checking the log, I see the findMe() is only called once, but not be repeated as that I expect.

I also tried changing findMe() ==> findMe

setInterval(this.findMe, 3000);

this time, the log repeatedly appears, however there is always a error:

ERROR TypeError: _this.showPosition is not a function

Could you please help how can I repeatedly calling findMe() and why the error happens?

lealceldeiro
  • 14,342
  • 6
  • 49
  • 80
Sunny Lei
  • 181
  • 1
  • 3
  • 15
  • I have only showPosition() as given in above code. findMe() function call this function using this.showPostion(). – Sunny Lei Jul 19 '18 at 13:21
  • 1
    Possible duplicate of [How to access the correct \`this\` inside a callback?](https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback) – Heretic Monkey Jul 19 '18 at 13:27

4 Answers4

1

The correct way to invoke the interval is with the function declaration setInterval(this.findMe, 3000);. As you noted, if you include the () it is only executed once.

One of the issues that comes up with setInterval is that it changes the this context of the executing function. To fix this, you need to force it to be constant.

constructor(public globalvar: GlobalvarService) {
  this.findMe = this.findMe.bind(this);
}

Additional info:

Vlad274
  • 6,514
  • 2
  • 32
  • 44
1

You can just use an arrow function that preserves this context :

setInterval(() => this.findMe(), 3000);
Guerric P
  • 30,447
  • 6
  • 48
  • 86
1

You can use arrow function syntax to make it work.

ngOnInit() {
    setInterval(() => {
        this.findMe()
    }, 4000);
}

findMe = () => {
    console.log('found');
}

Arrow function is referencing this as Component at all times.

Example - https://stackblitz.com/edit/angular-wkv2he

Gregor Ojstersek
  • 1,369
  • 7
  • 12
1

Try

 setInterval(() => {
    this.findMe()
 }, 3000);

But I think than better solution is to use Observable interval.

interval(3000).subscribe(res => {
   this.findMe()
})

Or in older versions of Angular :)

Observable.interval(3000).subscribe(res => {
   this.findMe()
})
Jakub
  • 143
  • 8