Why is Viewer' getViewerToken getting called infinite times? - autodesk-forge

The function getViewerToken is called infinitely since today without any code change. Is this bug on our side or a bug in the forge viewer?
iframe.viewer = new iframe.Autodesk.Viewing.GuiViewer3D(iframe.viewerDiv, { extensions: extensions });
let options = {
// 'env': 'AutodeskProduction',
'env': 'MD20ProdEU', //svf2
'api': 'D3S', //svf2
'getAccessToken': function(onTokenReady) {
...
};
.....

The viewer calls the getAccessToken function whenever the token needs to be refreshed. When you're calling the callback function inside getAccessToken, make sure that the second parameter (expiration time of the new token in seconds) is a positive integer number. Perhaps your code is passing in zero or a negative number, forcing the viewer to repeatedly ask for new tokens.

Related

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

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
});

Returning promise from reflux store

I'm working on my first react/reflux app so I may be approaching this problem in completely the wrong way. I'm trying to return a promise from a reflux store's action handler. This is the minimum code that represents how I'm trying to do this. If I display this in the browser, I get an error saying that the promise is never caught, because the result of the onLogin function is not passed back when the action is initiated. What is the best way to do this?
var Reflux = require('reflux');
var React = require('react/addons')
const Action = Reflux.createAction();
const Store = Reflux.createStore({
init: function() {
this.listenTo(Action, this.onAction);
},
onAction: function(username, password) {
var p = new Promise((resolve, reject) => {
reject('Bad password');
});
return p;
}
});
var LoginForm = React.createClass({
mixins: [Reflux.connect(Store, 'store')],
login: function() {
Action('nate', 'password1').catch(function(e) {
console.log(e); // This line is never executed
});
},
render: function() {
return (
<a onClick={this.login} href="#">login</a>
)
}
});
React.render(<LoginForm />, document.body);
Several things seem a bit confused here.
Reflux.connect(Store, 'store') is a shorthand for listening to the provided store, and automatically set the "store" property of your component state to whatever is passed in your store's this.trigger() call. However, your store never calls this.trigger so "store" in your component's state will never be updated. Returning a value from your store's action handlers doesn't trigger an update.
Stores should listen to actions to update their internal state, and typically then broadcast this state update by calling this.trigger. No component is going to get your returned promise from the store's onAction unless it explicitly calls Store.onAction (and then it doesn't matter if the actual action was invoked or not).
Async work should typically happen in the action's preEmit hook, not in the store. You should then also declare the action as async in createAction by setting the asyncResult option to true to automatically create "completed" and "failed" child actions. Check out the Reflux documentation here to learn about async events. Async actions automatically return promises, whose resolve and reject are called when the "completed" and "failed" sub-actions are called respectively. This is a bit opinionated, but that is definitely what I perceive is the intended Reflux way.

chrome.storage.sync vs chrome.storage.local

I was trying to understand how to use the chrome.storage.api.
I have included the following in my manifest.json:
"permissions": [
"activeTab","storage"
],
Than, I opened a new tab with the devtools and switched the <page context> to the one of my chrome-extension. Than I typed:
chrome.storage.sync.set({"foo":"bar"},function(){ console.log("saved ok"); } );
and got:
undefined
saved ok
Than I tried getting this stored value:
chrome.storage.sync.get("foo",function(data){ console.log(data); } );
but this got me:
undefined
Object {}
Than I did the same, but instead of sync I used local and this worked as expected:
chrome.storage.local.set({"foo":"bar"},function(){ console.log("saved ok"); } );
..and the retrieval:
chrome.storage.local.get("foo",function(data){ console.log(data); } );
Which got me: Object {foo: "bar"} as it should.
Is this because I am not signed in to my account on chrome? But in that case, isn't chrome.storage.sync designed to fallback into storing the data locally?
EDIT
Strangely, when i type this straight on console it seems to be working, but this code doesn't run from background.js code inside a click listener:
var dataCache = {};
function addStarredPost(post)
{
var id = getPostId(post);
var timeStamp = new Date().getTime();
var user = getUserName();
dataCache[id] = {"id":id,"post":post,"time":timeStamp,"user":user};
chrome.storage.sync.set(dataCache,function(){ console.log("Starred!");});
}
After this is ran, chrome.storage.sync.get(null,function(data){ console.log(data); }); returns an empty object as if the data wasn't stored. :/
This code seems to be working perfect with chrome.storage.local instead.
chrome.runtime.lastErros returns undefined
The max size for chrome local storage is 5,242,880 bytes.
To extend the storage you can add on the manifest.json :
"permissions": [
"unlimitedStorage"
]
The max size for chrome sync storage is:
102,400 bytes total
8,192 bytes per item
512 items max
1,800 write operations per hour
120 operations per minutes
(source)
Whoops!
The problem was I was trying to sync data that exceeded in size. (4096 Bytes per item)
I wasn't getting chrome.runtime.lastError because I was mistakenly putting it inside the get function scope, instead of the set function which was producing the error. Hence, I'm posting this answer so it might help others who share the same confusion.
You should check chrome.runtime.lastError inside each api call, like so:
chrome.storage.local.set(objectToStore, function(data)
{
if(chrome.runtime.lastError)
{
/* error */
console.log(chrome.runtime.lastError.message);
return;
}
//all good. do your thing..
}
This ran OK with chrome.storage.local because according to the docs you only have this limitation with sync.
printing chrome.runtime.lastError gave me: Object {message: "QUOTA_BYTES_PER_ITEM quota exceeded"}

Setting options outside of the constructor in FineUploader

My question is how would I set options outside of the constructor, if possible? For example, my request object depends of the type of file selected, so I have to build that object after the construction of the FineUploader object. Also, I want to set certain callbacks outside of the constructor, and have tried stuff like:
this.uploader =
new qq.FineUploaderBasic({button: btnAF,
debug: true,
multiple: false,
callbacks:{
onSubmitted: lang.hitch(this, this._addFile)
},
autoUpload: false});
And then some where else in the code:
var request = { endpoint: '/some/url/yada/yada/yada'};
this.uploader.request = request;
this.uploader.callbacks.onComplete = function(id, .... ) { alert ('Woo hoo!'); }
this.uploader.uploadStoredFiles();
However, it doesn't seem to work like this, and I didn't see any "setters" in the API doc that would allow me to set these on the fly.
The setEndpoint method lets you set the endpoint at any time for a specific file or for all files. It's not clear why you would want to replace your callback handlers on the fly. Callback handlers you supply are functions, which means the logic associated with each callback is already dynamic. Adjust the behavior of a handler based on the parameters passed into the handler, or some other in scope variable you control.

html5-geolocation : navigator.geolocation.watchPosition continuous callbacks

I am using the HTML5 geolocation API. I recently decided to shift from polling user position to
using the watchPosition method, which is supposed to fire its "success" function, once the device position changes.
But instead, it is filling up my database with the same position over and over again. Relevant code posted below:
updateLocation = navigator.geolocation.watchPosition(success, failed, {enableHighAccuracy:true, maximumAge:30000, timeout:27000});
function success(){
showGPS(position);
}
function showGPS(position) {
var lng = position.coords.longitude;
var lat = position.coords.latitude;
gpsText.innerText = "Latitude: "+ lat +"\nLongitude: "+ lng + "\nAccuracy: "+ position.coords.accuracy + "\nSpeed:" + (position.coords.speed*3.6) + "\nAltitude:" + position.coords.altitude;
getData("http://databaseEntryURL/gpsReceiver.aspx?string=" + gpsText.innerText);
}
The getData gets called about 5 times a second. I'm sure the latlng is not changing. I'm using android 2.2, to load this page. How do i make it call the success function ONLY if the device position changes?
Maybe it's just caused by some bug, so even when the location has no change (or the change is so small) your callback is still triggered.
One way to solve it is storing the last location and using it to compare with the current location. If there's no change (or the change is too small), do nothing in the callback. This will save you bandwidth and database space.
If you need to save battery life for the phone then you need to optimize the options, for example, changing enableHighAccuracy to false.
A more efficient way would be to set the watchPosition as a variable and call clearWatch() on it once you've received the first response:
var watchID = navigator.geolocation.watchPosition(onSuccess, onFailed);
function onSuccess(position) {
navigator.geolocation.clearWatch(watchID);
};