Google Earth Engine – Solving ‘Cannot Read Property Percentile of Undefined’ Error

google-earth-engine

I have a problem running the code below. I'm using the API through Node js. I receive

TypeError: Cannot read property 'percentile' of undefined

I don't understand why. Can you help me, please?

function test() {
      ee.data.authenticateViaPrivateKey(config.gee, async () => {

          console.log('init')
          var geometry = await ee.Geometry.Polygon([[[-58.22065005792236, -38.39475941140011],[-58.21198115838623, -38.391698569574615],[-58.222109179626464, -38.38813303001853]]])

          var collection = await ee.ImageCollection('COPERNICUS/S2').filterBounds(geometry).filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 5));

          var cloudMasked = await collection.map((image) => {
            var cloud = ee.Number(2).pow(10).int();
            var cirrus = ee.Number(2).pow(11).int();
            var qa = image.select('QA60');
            var mask = qa.bitwiseAnd(cloud).eq(0).and(qa.bitwiseAnd(cirrus).eq(0));
            return image.updateMask(mask);
          });

          var ndvi = await cloudMasked.map((image) => {
            return image.addBands(image.normalizedDifference(['B8', 'B4']).rename('NDVI'));
          });

          var reducer = ee.Reducer.percentile([90]);
          var ndvi90 = await ndvi.select(['NDVI']).reduce(reducer).clip(geometry);

          var url = await ndvi90.getDownloadURL({'scale': 10})

          console.log(url); 


      });
}

Is the use of async/await correct?

Best Answer

TypeError: Cannot read property 'percentile' of undefined

This means that you have not initialized the Earth Engine API with ee.initialize(). This is a separate step from authentication.

Many of the Earth Engine API calls are defined by the server, so they do not exist until the initialization, which downloads their declarations.

Is the use of async/await correct?

No. Earth Engine's ComputedObjects are not Promises, and awaiting them will do nothing. Promises are references to values that are being computed; a ComputedObject is a description of how to compute a value. EE API calls like select() compose into more complex ComputedValues, and the computation is actually started when you call an operation like getDownloadURL.

Just remove all of the await and your code will be correct (unless there's another problem you haven't seen and asked about yet).

Related Question