So I am trying to call a function outside of my
window.addEventListener('deviceorientation', function (event) { console.log(event.alpha + ' : ' + event.beta + ' : ' + event.gamma); this.adjustHeading(event.alpha); })
the function that I am trying to call:
adjustHeading: function (heading) { this.map.getModel().setViewRotation(heading, false); }
The whole js:
(function ($) { 'use strict'; $.widget("symfony.GpsPosition", { //lots of code// listenForDeviceOrientation: function() { window.addEventListener('deviceorientation', function (event) { console.log(event.alpha + ' : ' + event.beta + ' : ' + event.gamma); this.adjustHeading(event.alpha); })}, adjustHeading: function (heading) { this.map.getModel().setViewRotation(heading, false); } }); }(jQuery));
My problem is, that the this.adjustHeading(event.alpha);
call from the window.eventListener does not work because adjustHeading() is not available in the windows scope.
Is there any way to somehow bypass that and get access to the JS properties in the same file?
I am using smyfony and openlayers for the mapview, if that is helpfull at all.
Answer
The issue is because your code expects this
in the event handler function to be a reference to the settings object you provide to $.widget
. However in the event handler the scope has been changed so that this
refers to the object you attached the event to, the window
in this case.
To fix this you could either use an ES6 arrow functions to define the event handlers, as these do not affect the scope of the handler:
listenForDeviceOrientation: () => window.addEventListener('deviceorientation', e => this.adjustHeading(e.alpha)), adjustHeading: heading => this.map.getModel().setViewRotation(heading, false);
Or alternatively you could ‘cache’ the this
reference in a variable declared in the outer scope, to be used within the event handler:
$.widget("symfony.GpsPosition", { let _this = this; // lots of code... listenForDeviceOrientation: function() { window.addEventListener('deviceorientation', function(event) { _this.adjustHeading(event.alpha); }) }, adjustHeading: function(heading) { _this.map.getModel().setViewRotation(heading, false); } });
The former is more succinct but is not supported in IE, so the best choice for you would come down to what browsers you’re required to support.