Earth Engine client libraries for JavaScript and Python translate complex geospatial analyses to Earth Engine requests. Code that you write for a client library may contain a mixture of references to client-side objects and variables that represent server-side objects.
It is important to distinguish Earth Engine objects from other JavaScript objects or
primitives that might be in your code. You can manipulate objects on the server by
manipulating client-side “proxy” objects in your script. You can recognize a proxy
object as anything starting with ee
. These Earth Engine proxy objects do not
contain any actual data and are just handles for objects on the server. To start, consider
a client-side JavaScript string object (which is NOT a proxy object):
Code Editor (JavaScript)
var clientString = 'I am a String'; print(typeof clientString); // string
Observe from the console output that the web browser (which is called the 'client' in this
doc) has interpreted this code and run it, determining that the clientString
is type string
. Now suppose you want Earth Engine to be able to do
something with this string. To do that, you need to wrap up the string in a nice container
and send it to Google. That container is the proxy object. Here's an example:
Code Editor (JavaScript)
var serverString = ee.String('I am not a String!'); print(typeof serverString); // object print('Is this an EE object?', serverString instanceof ee.ComputedObject); // true
Observe from the console output that the ee.String
is an object
,
NOT a string
. More specifically, it's an ee.computedObject
, which
means it's a proxy object for something on the server. Think of ee.Thing
as
the way to put a thing in a container for sending to Google. Your client doesn't know
what's in the container, but you can find out what's in it by printing it:
Code Editor (JavaScript)
print(serverString); // I am not a String
To see what the container itself looks like, call toString()
on the object:
Code Editor (JavaScript)
print(serverString.toString()); // ee.String("I am not a String!")
If all you need to do is find out what's in the container, then just print()
and inspect the result in the console. If, for some reason, you need to use JavaScript
running in the client to manipulate whatever is in the container, then use
getInfo()
to get the contents of the container and assign it to a variable:
Code Editor (JavaScript)
var someString = serverString.getInfo(); var strings = someString + ' Am I?'; print(strings); // I am not a String! Am I?
You shouldn't use getInfo()
unless you absolutely need to. If you call
getInfo()
in your code, Earth Engine will open the container and tell you
what's inside, but it will block the rest of your code until that's done. (You can
optionally provide a callback function to avoid that, but the better option is to do
everything on the server, if possible.)
Looping
Because the client doesn't know what's in server-side ee.Thing
objects,
JavaScript functionality such as conditionals and for-loops does not work with them. For
that reason, and to avoid synchronous calls to getInfo()
, use server
functions to the extent possible. For example, consider the following two ways of
creating a list:
Not recommended — client-side for-loop
Code Editor (JavaScript)
var clientList = []; for(var i = 0; i < 8; i++) { clientList.push(i + 1); } print(clientList);
Recommended — server-side mapping
Code Editor (JavaScript)
var serverList = ee.List.sequence(0, 7); serverList = serverList.map(function(n) { return ee.Number(n).add(1); }); print(serverList);
The server-side mapping example is a little silly because you could make the same list
simply with ee.List.sequence(1, 8)
, but it illustrates some important
concepts. The first concept is map()
which simply applies the same function
to everything in the list. Because this function is executed on the server, client-side
functions such as print()
won't work in a mapped function. For that reason,
the i + 1
code has to be replaced with the equivalent server-side code:
ee.Number(n).add(1)
. Importantly, n
is an object that only
exists on the server. Because the function doesn't know the type of its argument, it needs
to be cast to an ee.Number
.
It's also worth noting that occasionally client-side functionality is convenient. For
example, the previous for loop could be used to build a list and wrap it with a
server-side object:
Code Editor (JavaScript)
var toServerList = ee.List(clientList);
Realize that client-side processing is done in your browser, using your machine's CPU, so it can be less efficient than using Earth Engine to do the work on the server. Also, to avoid potentially surprising results, it is good practice to avoid mixing client and server functionality in your scripts. The Conditionals section provides an example of possibly unintended consequences.
Conditionals
Server-side objects don't necessarily work with client side functions and vice versa. For example, consider the case of a server-side Boolean variable:
Code Editor (JavaScript)
var myList = ee.List([1, 2, 3]); var serverBoolean = myList.contains(5); print(serverBoolean); // false
Note that the server-side Boolean results from executing a method on a server object. It
appears to be a client variable when you print()
it because
print()
opens the container and tells you what's inside. However, as shown
in the following example, the variable does not behave in a client-side conditional
because it is a server-side object. To correctly check a server-side boolean, use a
server-side function:
Not recommended — client-side conditional
Code Editor (JavaScript)
var clientConditional; if (serverBoolean) { clientConditional = true; } else { clientConditional = false; } print('Should be false:', clientConditional); // True!
Recommended — server-side conditional
Code Editor (JavaScript)
var serverConditional = ee.Algorithms.If(serverBoolean, 'True!', 'False!'); print('Should be false:', serverConditional); // False!
Client and Server Functions
The previous sections describe several reasons why it is inefficient or illogical to
mix client and server objects and functions. Which objects and functions are client-side
and which are server-side? In general, any thing initialized as ee.Thing
is a server object and any method on that object, ee.Thing.method()
, is a
server function. In contrast, any class in the Code Editor API reference that doesn't
start with ee
is client-side as well. Examples include print()
,
Map
, Export
and Chart
. Objects and functions that
appear in the
JavaScript
reference are client-side. Any
JavaScript literal object
you create is a client-side object. As noted previously, you can use client-side
functionality to create an object, then wrap it by supplying the client-side object to an
Earth Engine constructor, for example ee.String()
.