Geolocation.currentLocation() not working, giving null value using meteor(1.5.1) & mdg:geolocation(1.3.0) - google-maps

I am working in a meteor project(1.5.1) and using mdg:geolocation#1.3.0, and i am trying to get the value of Geolocation.currentLocation() but it is giving me null value and the behaviour is not the same for all the time, sometime it is giving me null value and sometime giving me proper value.
I have research for the long time, but not got the solution yet, if possible please provide solution with meteor#1.5.1 and with use of mdg:geolocation package.
Thanks in advance...

MDG has implemented mdg:geolocation for continuous geolocation and functions in this Meteor package return a reactive var. You can use the package this way (for example):
// Continous geolocation with mdg:geolocation
// This code will run every time user location changes.
Tracker.autorun(() => {
const position = Geolocation.currentLocation();
Tracker.nonreactive(() => {
if (position) {
Meteor.call('user.update.position', position);
}
});
});
If you don't need continous geolocation, You can use javascript method instead of meteor package. See this answer for other options with windows.navigator.geolocation. In this case you may need to add cordova-plugin-geolocation in case you are building Android or iOS apps
// Navigation geolocation to get geolocation only once
let errorCallback;
let successCallback;
successCallback = position => Meteor.call('user.update.position', position);
errorCallback = err => console.log(err);
navigator.geolocation.getCurrentPosition(successCallback, errorCallback, {
maximumAge: 60000,
timeout: 20000
});

Related

How to get a block's statut for a transaction in Ethereum network

This question follows a previous one that I asked : Trust Querying Event in Ethereum.
In my back-end I listen for an event after a specific transaction. My back-end get the event just after the transaction is added to a new block. However to be sure that the block will not be removed we need to wait that its statut becomes 'finalized'.
My question is : how can I manage to do it using ethersjs ?
Thanks,
I am just poking around stackoverflow for the first time and noticed your question. Since you're building automation around event monitoring, I wanted to recommend a great, free tool that handles this issue around block finality before exposing the event data you need via REST API.
https://www.hal.xyz/products/hal-stream
Hopefully it is helpful :)
I didn't manage to find an ideal solution. However I tried something like this and it seems to work :
provider.on(filter,async (log) => {
const listener ={
async action(){
try{
let iface = new ethers.utils.Interface(abi)
let amount = iface.parseLog(log).args.tokens;
let blockHash = log.blockHash;
let transactionHash = log.transactionHash;
let removed = log.removed;
if(!removed){
this.executedPayment = await ExecutedPayment.create(
{
PaymentId:uuid,
Amount:ethers.utils.formatUnits(amount, DECIMAL_USDT),
TransactionHash:transactionHash,
BlockHash:blockHash,
StateId:1
}
)
clearTimeout(this.finalizationTimeout);
this.finalizationTimeout = setTimeout(async () => {
await this.executedPayment.update({StateId:2})
await this.executedPayment.save()
provider.off(filter)
}, 900000) //if no reorgs happened in the last 15 minutes, we consider the block as finalized
}else{
this.executedPayment.update({StateId:3})
clearTimeout(this.finalizationTimeout);
}
}catch(e){
console.log("An error occured : "+e)
}
}
}
listener.action()
})
If you have another solution I'll be glad to know.

ResizeObserver - loop limit exceeded

About two months ago we started using Rollbar to notify us of various errors in our Web App. Ever since then we have been getting the occasional error:
ResizeObserver loop limit exceeded
The thing that confuses me about this is that we are not using ResizeObserver and I have investigated the only plugin which I thought could possibly be the culprit, namely:
Aurelia Resize
But it doesn't appear to be using ResizeObserver either.
What is also confusing is that these error messages have been occuring since January but ResizeObserver support has only recently been added to Chrome 65.
The browser versions that have been giving us this error are:
Chrome: 63.0.3239 (ResizeObserver loop limit exceeded)
Chrome: 64.0.3282 (ResizeObserver loop limit exceeded)
Edge: 14.14393 (SecurityError)
Edge: 15.15063 (SecurityError)
So I was wondering if this could possibly be a browser bug? Or perhaps an error that actually has nothing to do with ResizeObserver?
You can safely ignore this error.
One of the specification authors wrote in a comment to your question but it is not an answer and it is not clear in the comment that the answer is really the most important one in this thread, and the one that made me comfortable to ignore it in our Sentry logs.
This error means that ResizeObserver was not able to deliver all observations within a single animation frame. It is benign (your site will not break). – Aleksandar Totic Apr 15 at 3:14
There are also some related issues to this in the specification repository.
It's an old question but it still might be helpful to someone. You can avoid this error by wrapping the callback in requestAnimationFrame.
For example:
const resizeObserver = new ResizeObserver(entries => {
// We wrap it in requestAnimationFrame to avoid this error - ResizeObserver loop limit exceeded
window.requestAnimationFrame(() => {
if (!Array.isArray(entries) || !entries.length) {
return;
}
// your code
});
});
If you're using Cypress and this issue bumps in, you can safely ignore it in Cypress with the following code in support/index.js or commands.ts
const resizeObserverLoopErrRe = /^[^(ResizeObserver loop limit exceeded)]/
Cypress.on('uncaught:exception', (err) => {
/* returning false here prevents Cypress from failing the test */
if (resizeObserverLoopErrRe.test(err.message)) {
return false
}
})
You can follow the discussion about it here.
As Cypress maintainer themselves proposed this solution, so I believe it'd be safe to do so.
We had this same issue. We found that a chrome extension was the culprit. Specifically, the loom chrome extension was causing the error (or some interaction of our code with loom extension). When we disabled the extension, our app worked.
I would recommend disabling certain extensions/addons to see if one of them might be contributing to the error.
For Mocha users:
The snippet below overrides the window.onerror hook mocha installs and turns the errors into a warning.
https://github.com/mochajs/mocha/blob/667e9a21c10649185e92b319006cea5eb8d61f31/browser-entry.js#L74
// ignore ResizeObserver loop limit exceeded
// this is ok in several scenarios according to
// https://github.com/WICG/resize-observer/issues/38
before(() => {
// called before any tests are run
const e = window.onerror;
window.onerror = function(err) {
if(err === 'ResizeObserver loop limit exceeded') {
console.warn('Ignored: ResizeObserver loop limit exceeded');
return false;
} else {
return e(...arguments);
}
}
});
not sure there is a better way..
add debounce like
new ResizeObserver(_.debounce(entries => {}, 200);
fixed this error for me
The error might be worth investigating. It can indicate a problem in your code that can be fixed.
In our case an observed resize of an element triggered a change on the page, which caused a resize of the first element again, which again triggered a change on the page, which again caused a resize of the first element, … You know how this ends.
Essentially we created an infinite loop that could not be fitted into a single animation frame, obviously. We broke it by holding up the change on the page using setTimeout() (although this is not perfect since it may cause some flickering to the users).
So every time ResizeObserver loop limit exceeded emerges in our Sentry now, we look at it as a useful hint and try to find the cause of the problem.
In my case, the issue "ResizeObserver - loop limit exceeded" was triggered because of window.addEventListener("resize" and React's React.useState.
In details, I was working on the hook called useWindowResize where the use case was like this const [windowWidth, windowHeight] = useWindowResize();.
The code reacts on the windowWidth/windowHeight change via the useEffect.
React.useEffect(() => {
ViewportService.dynamicDimensionControlledBy(
"height",
{ windowWidth, windowHeight },
widgetModalRef.current,
{ bottom: chartTitleHeight },
false,
({ h }) => setWidgetHeight(h),
);
}, [windowWidth, windowHeight, widgetModalRef, chartTitleHeight]);
So any browser window resize caused that issue.
I've found that many similar issues caused because of the connection old-javascript-world (DOM manipulation, browser's events) and the new-javascript-world (React) may be solved by the setTimeout, but I would to avoid it and call it anti-pattern when possible.
So my fix is to wrap the setter method into the setTimeout function.
React.useEffect(() => {
ViewportService.dynamicDimensionControlledBy(
"height",
{ windowWidth, windowHeight },
widgetModalRef.current,
{ bottom: chartTitleHeight },
false,
({ h }) => setTimeout(() => setWidgetHeight(h), 0),
);
}, [windowWidth, windowHeight, widgetModalRef, chartTitleHeight]);
One line solution for Cypress. Edit the file support/commands.js with:
Cypress.on(
'uncaught:exception',
(err) => !err.message.includes('ResizeObserver loop limit exceeded')
);
https://github1s.com/chromium/chromium/blob/master/third_party/blink/renderer/core/resize_observer/resize_observer_controller.cc#L44-L45
https://github1s.com/chromium/chromium/blob/master/third_party/blink/renderer/core/frame/local_frame_view.cc#L2211-L2212
After looking at the source code, it seems in my case the issue surfaced when the NotifyResizeObservers function was called, and there were no registered observers.
The GatherObservations function will return a min_depth of 4096, in case there are no observers, and in that case, we will get the "ResizeObserver loop limit exceeded" error.
The way I resolved it is to have an observer living throughout the lifecycle of the page.
Managed to solve this in React for our error logger setup.
The Observer error propagates to the window.onerror error handler, so by storing the original window.onerror in a ref, you can then replace it with a custom method that doesn't throw for this particular error. Other errors are allowed to propagate as normal.
Make sure you reconnect the original onerror in the useEffect cleanup.
const defaultOnErrorFn = useRef(window.onerror);
useEffect(() => {
window.onerror = (...args) => {
if (args[0] === 'ResizeObserver loop limit exceeded') {
return true;
} else {
defaultOnErrorFn.current && defaultOnErrorFn.current(...args);
}
};
return () => {
window.onerror = defaultOnErrorFn.current;
};
}, []);
I had this issue with cypress tests not being able to run.
I found that instead of handling the exception the proper way was to edit the tsconfig.json in a way to target the new es6 version like so:
{
"extends": "../tsconfig.json",
"compilerOptions": {
"baseUrl": "../node_modules",
"target": "es5", --> old
"target": "es6", --> new
"types": ["cypress", "#testing-library/cypress"],
"sourceMap": true
},
"include": [
"**/*.ts"
]
}

Loading Aurelia breaks Google API

I have created a reproduction of this bug here (ugly use of Aurelia but to prove the point): https://jberggren.github.io/GoogleAureliaBugReproduce/
If I load Google API and try to list my files in Google Drive my code derived from Googles quickstart works fine. If I use the same code after loading Aurelia I get a script error from gapi stating
Uncaught Error: arrayForEach was called with a non array value
at Object._.Sa (cb=gapi.loaded_0:382)
at Object._.eb (cb=gapi.loaded_0:402)
at MF (cb=gapi.loaded_0:723)
at Object.HF (cb=gapi.loaded_0:722)
at Object.list (cb=gapi.loaded_0:40)
at listFiles (index.js:86)
...
When debugging it seems to be some sort of array check (Chroms says 'native code') that failes after Aurelia is loaded. In my search for an answer I found two other people with the same problem but no solution (Aurelia gitter question, SO Question). Don't know if to report this to the Aurelia team, Google or where the actual problem lays.
Help me SO, you are my only hope.
This is not a perfect solution but works.
aurelia-binding
https://github.com/aurelia/binding/blob/master/src/array-observation.js
Aurelia overrides Array.prototype.* for some reasons.
gapi (especially spreadsheets)
Gapi lib checks to make sure that is it native code or not.
// example
const r = /\[native code\]/
r.test(Array.prototype.push)
conclusion
So, we have to monkey patching.
gapi.load('client:auth2', async () => {
await gapi.client.init({
clientId: CLIENT_ID,
discoveryDocs: ['https://sheets.googleapis.com/$discovery/rest?version=v4'],
scope: 'https://www.googleapis.com/auth/spreadsheets',
});
// monkey patch
const originTest = RegExp.prototype.test;
RegExp.prototype.test = function test(v) {
if (typeof v === 'function' && v.toString().includes('__array_observer__.addChangeRecord')) {
return true;
}
return originTest.apply(this, arguments);
};
});

Accessing indexedDB in ServiceWorker. Race condition

There aren't many examples demonstrating indexedDB in a ServiceWorker yet, but the ones I saw were all structured like this:
const request = indexedDB.open( 'myDB', 1 );
var db;
request.onupgradeneeded = ...
request.onsuccess = function() {
db = this.result; // Average 8ms
};
self.onfetch = function(e)
{
const requestURL = new URL( e.request.url ),
path = requestURL.pathname;
if( path === '/test' )
{
const response = new Promise( function( resolve )
{
console.log( performance.now(), typeof db ); // Average 15ms
db.transaction( 'cache' ).objectStore( 'cache' ).get( 'test' ).onsuccess = function()
{
resolve( new Response( this.result, { headers: { 'content-type':'text/plain' } } ) );
}
});
e.respondWith( response );
}
}
Is this likely to fail when the ServiceWorker starts up, and if so what is a robust way of accessing indexedDB in a ServiceWorker?
Opening the IDB every time the ServiceWorker starts up is unlikely to be optimal, you'll end up opening it even when it isn't used. Instead, open the db when you need it. A singleton is really useful here (see https://github.com/jakearchibald/svgomg/blob/master/src/js/utils/storage.js#L5), so you don't need to open IDB twice if it's used twice in its lifetime.
The "activate" event is a great place to open IDB and let any "onupdateneeded" events run, as the old version of ServiceWorker is out of the way.
You can wrap a transaction in a promise like so:
var tx = db.transaction(scope, mode);
var p = new Promise(function(resolve, reject) {
tx.onabort = function() { reject(tx.error); };
tx.oncomplete = function() { resolve(); };
});
Now p will resolve/reject when the transaction completes/aborts. So you can do arbitrary logic in the tx transaction, and p.then(...) and/or pass a dependent promise into e.respondWith() or e.waitUntil() etc.
As noted by other commenters, we really do need to promisify IndexedDB. But the composition of its post-task autocommit model and the microtask queues that Promises use make it... nontrivial to do so without basically completely replacing the API. But (as an implementer and one of the spec editors) I'm actively prototyping some ideas.
I don't know of anything special about accessing IndexedDB from the context of a service worker via accessing IndexedDB via a controlled page.
Promises obviously makes your life much easier within a service worker, so I've found using something like, e.g., https://gist.github.com/inexorabletash/c8069c042b734519680c to be useful instead of the raw IndexedDB API. But it's not mandatory as long as you create and manage your own promises to reflect the state of the asynchronous IndexedDB operations.
The main thing to keep in mind when writing a fetch event handler (and this isn't specific to using IndexedDB), is that if you call event.respondWith(), you need to pass in either a Response object or a promise that resolves with a Response object. As long as you're doing that, it shouldn't matter whether your Response is constructed from IndexedDB entries or the Cache API or elsewhere.
Are you running into any actual problems with the code you posted, or was this more of a theoretical question?

Geolocation HTML5 enableHighAccuracy True , False or Best Option?

i have a problem about HTML5 geolocation feature. I use the code below to get location data. I use "enableHighAccuracy: false" option to work with Cell Based GPS feature. Accurancy is low but response it too fast. But some people always use Built-in GPS with their mobile phone, so this code does not work for them. Bu if i change accurency option as "enableHighAccuracy: true" it works for them. But this time, the code uses only built-in GPS. not CELL based GPS.
The question -> How can i do that : First, try to get position from Built-in GPS with timeout (e.g. 5000ms ) if position cannot be got in this time just look for Cell Based position for timeout (e.g. 10000ms) if position cannot be get in this time, return an error message .
Here is the code that i use now.
Thanks in advance.
function getLocationfromGoogle() {
navigator.geolocation.getCurrentPosition(
function(pos) {
$("#lat_field").val(pos.coords.latitude);
$("#long_field").val(pos.coords.longitude);
var geocoder = new google.maps.Geocoder();
var latLng = new google.maps.LatLng(pos.coords.latitude,pos.coords.longitude);
geocoder.geocode({ 'latLng': latLng}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
//console.log(results[0].formatted_address);
$("#adresim").val(results[0].formatted_address);
}
else {
alert('Google convertion is not succesfully done.');
}
});
},function error(msg){
alert('Please enable your GPS position future.');
},{maximumAge:600000, timeout:5000, enableHighAccuracy: false}
);
}
You should also be aware that the implementation of this varies from phone OS to phone OS - what works on Android may or may not work on iOS, BlackBerry, WindowsPhone, etc.
You're almost there, you just need to:
Specify enableHighAccuracy: true (you have it set to false)
Handle the timeout error case in the error handler. If the error from the high accuracy query is timeout, then try it again with enableHighAccuracy: false.
Have a look at this sample code.
You should also note that when testing this on a few devices, it returns location derived from WiFi even when enableHighAccuracy: true.
The code mentioned here: http://jsfiddle.net/CvSW4/ did not work for me during error handling.
The reason is that the error functions accept a parameter named 'position' but use an object in the functions called 'error'.
function errorCallback_highAccuracy(position) { ... }
function errorCallback_lowAccuracy(position) { ... }
The solution to fix this was to switch the error methods to accept the input value as a parameter named 'error' and not 'position', since the error callbacks do not accept a position and throw an error object instead.
function errorCallback_highAccuracy(error) { ... }
function errorCallback_lowAccuracy(error) { ... }
I mention it here, because I could not post on the resulting example page and also, this is the location where I linked through to find the code sample mentioned above.