Calling functions from other scripts within Google Earth Engine - javascript

This is my first project using javascript. I am developing a set of scripts in order to acquire multiple types of data in the same area scope in google earth engine. In doing this, I could make large script to do this but would rather call functions from other scripts. I have tried multiple solutions to do this, though they were a while ago and I, unfortunately, have lost them to time. One of the primary issues that I have run into is most of the javascript help I have seen is for use in web pages not backend development.
Any questions about this are welcome and would like to learn how to make better questions if you have constructive criticism?

This is possible using the require function. In short, write a code file with anything you wish to export named as an "exports" variable, e.g.
exports.scale = 30;
Then save it and remember where it is.
Load it in another script using require, like this:
var constants = require('users/me/that_script.js');
And refer to the exported variable using constants.scale.
More info here

Related

Conflicting global variable names in external javascript

There are a lot of questions and answers about conflicting variables names on Stackoverflow, but they all seem to be about scoping in your own code.
<script src="https://external_one/some_script.js"></script>
<script src="https://external_two/another_script.js"></script>
I'm loading two external, 3rd party JS scripts and need to run them on the same webpage. Separately they work fine, but when I try to import both at the same time, I run into a problem: both scripts have been written in such a way that they use a global _ variable. This means only the script that was imported last will work, as it overwrites the existing _ variable from the first script.
Using a global variable like this is bad practice and using a generic variable name like _ makes it even worse, but as these scripts are rather complex I can't just write my own version and I'm stuck using the scripts from these two providers. They don't seem to provide something like the 'no conflict' option libraries like JQuery provide (to prevent breaking other script that use the $ variable).
So what I'm was trying to figure out, is if it's somehow possible to encapsulate those scripts on import and prevent them from using the same variable. The only option I could think of was to use ajax to load the script, maybe make some changes and then run it using eval but this sounds like a huge problem waiting to happen.
Any suggestions on how to solve this problem?

How to include OVRManager in Three.js Scene?

I have created several Three.js/Javascript demo applications that I'm experimenting with in my new Oculus Go. I'm trying to enable the Go Controller to do stuff in my applications, and according to the Oculus Developer Center, the best thing to do is to include OVRManager in my scene so I have access to that API. That sounds good, but for all the documentation (https://developer.oculus.com/documentation/unity/latest/concepts/unity-ovrinput/) I can't see HOW to add OVRManager to my scene! I have not worked with Unity before, but from what I can tell in the documentation there shouldn't be any compatibility issues (should there?)
So what I'd think to do is something like:
<script src="OVRManager.js or something like that"></script>
and then call the functions I need, as I've done with OrbitControls.js and other external dependencies.
But for the life of me, Google searching is just sending me in circles. I see questions posed for C++ and C# but that's of no use to me. How do I get this API working in my Three.js scene? Where do I find it and is there some other way to include it?
Thanks!
Create a unity WebGL build and expose the API you need as public methods in a Unity Script you attach to a GameObject.
Then, you should be able to follow the directions at How to call Unity functions from javascript (copied below) on how to call those methods from your javascript code.
You may be able to use UnityScript, which is vaguely similar to JavaScript, to write the Script if you use an old version of Unity. As of this writing, Oculus recommends version 2017.4.11f1, which I think might still support UnityScript.
One major reason you see so much less UnityScript information is that Unity has been moving away from UnityScript, into only supporting C#.
But regardless of if you code your OVRManager script in C# or UnityScript, Unity will make the methods callable from your JavaScript.
Calling Unity scripts functions from JavaScript
Sometimes you need to send some data or notification to the Unity
script from the browser’s JavaScript. The recommended way of doing it
is to call methods on GameObjects in your content. If you are making
the call from a JavaScript plugin, embedded in your project, you can
use the following code:
SendMessage(objectName, methodName, value);
Where objectName is the name of an object in your scene; methodName is
the name of a method in the script, currently attached to that object;
value can be a string, a number, or can be empty. For example:
SendMessage('MyGameObject', 'MyFunction');
SendMessage('MyGameObject', 'MyFunction', 5);
SendMessage('MyGameObject', 'MyFunction', 'MyString');
If you would like to make a call from the global scope of the
embedding page, see the Code Visibility section below.
Code visibility
Starting from Unity 5.6 all the build code is executed in its own
scope. This approach makes it possible to embed your game on an
arbitrary page without causing conflicts with the embedding page code,
as well as makes it possible to embed more than one build on the same
page.
If you have all your JavaScript code in the form of .jslib plugins
inside your project, then this JavaScript code will run inside the
same scope as the compiled build and your code should work pretty much
the same way as in previous versions of Unity (for example, the
following objects and functions should be directly visible from the
JavaScript plugin code: Module, SendMessage, HEAP8, ccall etc.).
However, if you are planning to call the internal JavaScript functions
from the global scope of the embedding page, you should always assume
that there are multiple builds embedded on the page, so you should
explicitly specify which build you are referencing to. For example, if
your game has been instantiated as:
var gameInstance = UnityLoader.instantiate("gameContainer", "Build/build.json", {onProgress: UnityProgress});
Then you can send a message to the build using
gameInstance.SendMessage(), or access the build Module object using
gameInstance.Module.

Make an external Script available to all members of qooxdoo Object

So I have been making a web app in the qooxdoo framework that utilised the d3 library. At the moment, every function which needs to use the d3 library works like this:
myFunction : function() {
var req = new qx.bom.request.Script();
req.onload = this.myActualFunction(); //calls function when script loads
req.open("GET","http://d3js.org/d3.v3.js" );
req.send();
}
It seems verbose to have to call the script loader for lots of different functions*. We could, and eventually probably will, switch to using d3 from a local directory. Nevertheless, it seems like there are lots of times when you would like to use a script loader to make a script available to, say, every member function of an object. Is there someway that I can achieve that? If I passed the script loader around like a variable, does that mean that every function which has it in scope gets access to the library?
The Manual did not appear very helpful on this topic.
*I presume that qooxdoo arranges to cache the script - it seems to be pretty good at those type of optimisations, though I have no specific knowledge of how the script loaders are treated in the compiled version.
The best approach of handling an external library is to create a Qooxdoo wrapper which will be a first-class citizen in the dependency management process. Qooxdoo internally makes use of this approach, e.g. Sizzle, Mustache, etc. Luckily for you there's already a contribution for D3. Though you can make your own wrapper without a hassle.
You can also, use add-script to "link" the library to the document but I see this way mostly disadvantageous.

Create and Call External JS files

I've spent a great deal of time creating and testing an application with quite a few functions. Now that I have configured everything and it works how I want, I would like to begin cleaning up the code so its not 400 lines of mush.
I have already created an external CSS file and would like to do something similar for the JS and possibly even the HTML (approx 100 lines of code of just HTML, ick).
Admittedly I am a novice programmer but I've picked up quite a bit of knowledge in the short time I've been doing this. What is the best way to separate out the functions into external files and then call them so that the whole application works as it does now?
For example (this is a web mapping application): I have functions for search, basemap gallery, legend, layers, init, infowindows, etc. Since the code is already written and I'll be creating multiple applications in the future, the goal would be to just have these js functions in files ready to be referenced by whatever application needs them.
Thanks.
To link an external javascript file, place a script tag with a src attribute pointing to your file.
<script src="legend.js"></script>
<script src="layers.js"></script>
<script src="init.js"></script>
Calling a function requires nothing special.
onclick="myFunction();"
Could you not just put all of those functions in one .js file and then call the file from within your web page?
<script src="../scripts/javascript.js"></script>
And then call on your functions as and when you need them?
The first thing you might consider doing do is to create a non-global "namespace" for your functions in a fashion such as the following:
window.MyApp = window.MyApp || {};
The above line can be at the top of every file; the first time it is invoked it creates a new namespace/object, subsequently it returns the one you previously created.
Then you can move your functions under MyApp in a manner such as the following:
MyApp.func1 = function() {...}
Google for creating Javascript namespaces, and possibly also the Javascript module pattern

what is google map's javascript load strategy

When I use google maps, I am interested in its implemention, so I use the firebug to inspect.
Then I found that its javascript loading strategy is rather interesting. Take this page for example:
The overlay example
Then when I open this page first time, the following js are loaded:
https://maps.googleapis.com/maps/api/js?sensor=false
https://maps.gstatic.com/intl/en_us/mapfiles/api-3/9/13b/main.js
https://maps.gstatic.com/cat_js/intl/en_us/mapfiles/api-3/9/13b/%7Bcommon,map,util,poly%7D.js
https://maps.gstatic.com/cat_js/intl/en_us/mapfiles/api-3/9/13b/%7Bonion,geometry%7D.js
But if I refresh the page(use the ctrl+f5), the following js are loaded:
https://maps.googleapis.com/maps/api/js?sensor=false
https://maps.gstatic.com/intl/en_us/mapfiles/api-3/9/13b/main.js
However the page still works, the overlay is drawn in the map. But where is the poly.js and etc?
Also, can anyone tell me how to load the js by components? For exmaple the common util poly in the example.
What should I know when I write the different components?
1. When poly.js loads, it passes a string to google.maps.__gjsload___.
Here's an excerpt:
google.maps.__gjsload__('common', '\'use strict\';var Ai=isNa...
The rest of the file is just the contents of that string.
My hunch is this function probably stores this string in localStorage or sessionStorage so that it only has to be retrieved once.
2. Also, if you want to learn about loading js files as-needed, look into AMD and/or CommonJS:Modules.
A good imlementation of AMD (my preference) is RequireJS.
Update
I did some poking around, and localStorage and sessionStorage do not appear to be being used on this page. I also can't duplicate your results. In Firebug, poly.js always loads for me. There may be some magic happening somewhere, but I don't see it.
However, it's entirely possible to store a string in localStorage and sessionStorage for retrieval without having to make an extra js call.
Also,any one can tell me how to load the js by components?
this touches on the topic of asynchronous javascript file loading. if you've ever used a language that has a way to "include" a file at any point in a script, you'll understand that javascript does not have this capability. because of that, there is this whole paradigm of "aysnc javascript addition" via script tag injection.
script tag injection: you dynamically make a script tag, and set its source to the file you need, and insert that tag into the DOM, and voila, a new file has been loaded and executed. With javascript heavy applications, this is common, especially when loading third party applications. Google does it alllll the time, just check out google analytics' include script for a good example of this.
Now, since this is a touchy and delicate type of coding to do, some "javascript component / module / asset loading" frameworks have refined it and made it pretty stable. common.js, require.js, etc have all done good jobs at this.
What should I know when I write the different components ?
For what you're doing with google maps, you don't really need to know much. but if you get into javascript module pattern development, you need to know this: make sure you protect your global namespace from being cluttered by your own variables, so encapsulate all of your work in closures when possible, and (recommended but not required) start them all with a ; so they don't break each other if they get loaded out of order.

Categories