Reputation: 8054
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)
Upvotes: 1
Views: 525
Reputation: 51
I think you can only use this
inside an instance because it has to refer to an instanciated object.
It looks like your solution is the proper way to write it.
I'm not sure, but inside your static class, I don't think you need to nest function calls like this:
static getPosition() {
return GeoService._position;
// return _position;
// may work as well
}
Upvotes: 0
Reputation: 8054
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);
}
}
Upvotes: 1