01-10-2018 13:15
01-10-2018 13:15
Hi All,
I am very new to class programming, so am probably doing something really stupid. I have started to move my project into Ionic Views by @gaperton which will work very well for my app.
Anyway, the problem is the following line of code never calls my class method:
watchID = geolocation.watchPosition(()=>this.gpsbeat,()=>this.gpsError);
Yet the following line of code calls the method, but loses scope to my variables:
watchID = geolocation.watchPosition(this.gpsbeat,this.gpsError);
Any help / pointers would be greatly appreciated. Thank you.
For reference, the rest of the runMaster.class.js file is below for a little more context:
import { HeartRateSensor } from "heart-rate";
import { geolocation } from "geolocation";
class runMaster {
readingNumber=0;
lat=0;
lon=0;
speed=0;
altitude=0;
sensorReadTimer=0;
hrmread=0;
hrm=0;
gps=0;
start() {
this.sensorReadTimer=setInterval(() => this.reading(),2000);
this.hrm=new HeartRateSensor();
this.hrm.onreading = () => this.hrmbeat();
watchID = geolocation.watchPosition(()=>this.gpsbeat,()=>this.gpsError);
this.hrm.start();
}
hrmbeat() {
this.hrmread=this.hrm.heartRate;
}
gpsbeat(position) {
this.lat=position.coords.latitude;
this.lon=position.coords.longitude;
this.speed=position.coords.speed;
this.altitude=position.coords.altitude;
this.readingNumber++;
console.log(this.lat+"::"+this.lon+"::"+this.speed+"::"+this.altitude);
}
gpsError() {
console.log("GPS Error");
}
reading() {
console.log("HR="+this.hrmread+" lat="+this.lat+" lon="+this.lon+" speed="+this.speed+" altitude="+this.altitude+" Reading #"+this.readingNumber);
}
returnval() {
return this.hrmread;
}
stop() {
clearInterval(this.sensorReadTimer);
console.log("Stop");
}
}
export default new runMaster();
Answered! Go to the Best Answer.
Best Answer01-10-2018 14:30 - edited 01-10-2018 14:32
01-10-2018 14:30 - edited 01-10-2018 14:32
There's another way of fixing this problem.
In the class definition, write:
gpsbeat = position => {
this.lat=position.coords.latitude;
this.lon=position.coords.longitude;
this.speed=position.coords.speed;
this.altitude=position.coords.altitude;
this.readingNumber++;
console.log(this.lat+"::"+this.lon+"::"+this.speed+"::"+this.altitude);
}
gpsError = () => {
console.log("GPS Error");
} It will pin down "this" to your methods, so they can be safely used as callbacks. Like this:
watchID = geolocation.watchPosition(this.gpsbeat,this.gpsError);
I actually prefer this way. Looks a bit nicer. But it's generally the matter of taste.
01-10-2018 14:16 - edited 01-10-2018 14:20
01-10-2018 14:16 - edited 01-10-2018 14:20
I'm sure it's a scope thing to do with 'this' in anonymous arrow functions
Early versions of JS got around this with something like
let that = this; // class scope
watchID = geolocation.watchPosition(()=>that.gpsbeat,()=>that.gpsError);
Best Answer01-10-2018 14:30 - edited 01-10-2018 14:32
01-10-2018 14:30 - edited 01-10-2018 14:32
There's another way of fixing this problem.
In the class definition, write:
gpsbeat = position => {
this.lat=position.coords.latitude;
this.lon=position.coords.longitude;
this.speed=position.coords.speed;
this.altitude=position.coords.altitude;
this.readingNumber++;
console.log(this.lat+"::"+this.lon+"::"+this.speed+"::"+this.altitude);
}
gpsError = () => {
console.log("GPS Error");
} It will pin down "this" to your methods, so they can be safely used as callbacks. Like this:
watchID = geolocation.watchPosition(this.gpsbeat,this.gpsError);
I actually prefer this way. Looks a bit nicer. But it's generally the matter of taste.
01-10-2018 14:32
01-10-2018 14:32
Thank you for the response @TechnoBuddhist - really appreciated.
I am sorry to report that doesn't seem to help 😞
Best Answer01-10-2018 14:37 - edited 01-10-2018 14:41
01-10-2018 14:37 - edited 01-10-2018 14:41
@SunsetRunner
And in fact, you originally did it almost right. Just forgot to call your functions from within your arrow functions, which was a valid no-op JS expression. It should be:
watchID = geolocation.watchPosition(()=>this.gpsbeat(),()=>this.gpsError());
The difference between function( x ){ return ... } and x => ... is that the last one capture "this". So, you don't need to work it around with "var _this" or something. The keyword is "JS arrow functions".
01-10-2018 14:39
01-10-2018 14:39
Thank you @gaperton. I obviously need to go and read more about classes .....
I am digging deep getting to grips with your Ionic Views, but it really will be worth it. I know the app I want and need, and your class will help.
Again, thank you.
Best Answer01-10-2018 14:57
01-10-2018 14:57
@gaperton Durrgh! yeah I remember reading this now - JS arrow function handles 'this'. That'll teach me to read as I go to sleep.
Obviously also missing the parenthesis off the call!
()=>this.gpsbeat(),()=>this.gpsError()
Lessons learnt! Cheers!