In my React Native application the class GeoService
is a set of static methods with two declared static variables id
and position
.
If I try to reference the static class variable from its own static method with the this
keyword, it seems to create a new variable in a different scope. Without this
keyword it gives an outright error that the variable is unresolved.
Does the static
keyword really mean anything useful in JS and what approach would work here to define static variables/methods?
CaptureView.js
:
class CaptureView extends Component {
constructor(props) {
super(props);
GeoService.start();
}
componentWillUnmount() {
GeoService.stop();
}
onButtonPress() {
Promise.all([this.cameraSrv.takePicture(), GeoService.getPosition()]).then(data => {
let lat = data[1].lat; // PROBLEM HERE - Cannot read property 'lat' of undefined
let log = data[1].lng;
});
}
}
GeoService.js
:
import Logger from '../utils/Logger';
export default class GeoService {
static _id = undefined;
static _position = undefined;
static start() {
GeoService._getQuickPosition();
GeoService._watchAccuratePosition();
}
static stop() {
GeoService._clearWatch();
}
static getPosition() {
return GeoService._position;
}
static _getQuickPosition() {
navigator.geolocation.getCurrentPosition(
GeoService._successCallback,
GeoService._errorCallback,
{enableHighAccuracy: false, timeout: 20000, maximumAge: 1000}
);
}
static _watchAccuratePosition() {
if (GeoService._id) {
return;
}
GeoService._id = navigator.geolocation.watchPosition(
GeoService._successCallback,
GeoService._errorCallback,
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
);
Logger.info('GeoService watch started');
}
static _clearWatch() {
navigator.geolocation.clearWatch(GeoService._id);
delete GeoService._id;
Logger.info('GeoService watch ended');
}
static _successCallback(position) {
GeoService._position = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
Logger.info('GeoService new position: ' + JSON.stringify(GeoService._position));
}
static _errorCallback(error) {
Logger.info('GeoService error: ' + error);
}
}
React Native console:
GeoService watch started
GeoService new position: {"lat":50.54822785298157,"lng":7.132454606843366}
GeoService new position: {"lat":50.54822785298157,"lng":7.132454606843366}
takePicture...
TypeError: Cannot read property 'lat' of undefined
at CaptureView.js:187
at tryCallOne (core.js:37)
at core.js:123
at JSTimers.js:298
at _callTimer (JSTimers.js:152)
at _callImmediatesPass (JSTimers.js:200)
at Object.callImmediates (JSTimers.js:473)
at MessageQueue.__callImmediates (MessageQueue.js:337)
at MessageQueue.js:135
at MessageQueue.__guard (MessageQueue.js:314)
Here is my solution, referring to static class variables as GeoService.xxx
:
import Logger from '../utils/Logger';
export default class GeoService {
static _id = undefined;
static _position = undefined;
static start() {
GeoService._getQuickPosition();
GeoService._watchAccuratePosition();
}
static stop() {
GeoService._clearWatch();
}
static getPosition() {
return GeoService._position;
}
static _getQuickPosition() {
navigator.geolocation.getCurrentPosition(
GeoService._successCallback,
GeoService._errorCallback,
{enableHighAccuracy: false, timeout: 20000, maximumAge: 1000}
);
}
static _watchAccuratePosition() {
if (GeoService._id) {
return;
}
GeoService._id = navigator.geolocation.watchPosition(
GeoService._successCallback,
GeoService._errorCallback,
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
);
Logger.info('GeoService watch started');
}
static _clearWatch() {
navigator.geolocation.clearWatch(GeoService._id);
delete GeoService._id;
Logger.info('GeoService watch ended');
}
static _successCallback(position) {
GeoService._position = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
Logger.info('GeoService new position: ' + JSON.stringify(GeoService._position));
}
static _errorCallback(error) {
Logger.info('GeoService error: ' + error);
}
}