Custom Layer with React and @esri/react-arcgis

1691
5
Jump to solution
11-11-2021 05:41 PM
RyanSutcliffe
Occasional Contributor II

I'm looking to implement a custom ArcGIS API for JavaScript baseElevationLayer like the example provided here. I basically take the example ESRI provide that creates a custom class and put it in a function `getClass` that returns the class for me. In vanilla JavaScript all seems to work fine. Here is a CodePen of the code

When I do the same thing in my React app, which uses esriLoader to load the API modules and react-arcgis to create a SceneView, loading this custom baseElevationLayer fails. Here is that in CodePen also.

If you look at the browser's developer console, you see an error about

"Cannot read properties of undefined (reading '_elevation')."

Can anyone spot what I'm missing? 

0 Kudos
1 Solution

Accepted Solutions
TomThompsonEsriCA
Esri Contributor

Further to this, In my test app, I loaded the v2.16 EsriLoader, without using any react classes or components, and the ExaggeratedElevationLayer is still working there. So this is not necessarily an issue with the older esriLoader version, or the older JS API version.

Sample app is here: https://codepen.io/tthompsonEsri/pen/XWayRqw?editors=0010

Seems specific to react classes, still trying to narrow it down.

 

Update:

Built out a custom component and passed it to the react Renderer(). It basically completely overlaps the React-arcgis.Scene component and does display the ExaggeratedElevation without issues. It's a lot of extra coding, but seems to work around the issue. 

https://codepen.io/tthompsonEsri/pen/VwzqNaX

 

Another Update:

 

Slightly more refined solution where the Scene in the child component is not overwriting the parent scene component.

https://codepen.io/tthompsonEsri/pen/mdMoWwL?editors=0010

View solution in original post

A CodePen implication of the 'create-react-app' package. ...
5 Replies
GavinRehkemper
Esri Contributor

Hi Ryan, thanks for the question. The first thing I'm noticing is that in your first CodePen, in the developer tools console it says "Using ArcGIS API for JavaScript 4.20" where in the second one the developer tools console it says "Using ArcGIS API for JavaScript 4.17". Which makes me think there's some issue with the second one where you're setting the API version.

TomThompsonEsriCA
Esri Contributor

Hey Gavin,

Thanks for taking the time to help out with this one. I'm working with Ryan on this issue through his case he's submitted through to Esri Canada Technical Support.

I've done some digging and have determined that the react-arcgis scene component uses an old version of the EsriLoader, and explains why we're seeing v4.17 consumed in the react application.

Once loading the <Scene/>, the calls are made to https://cdn.skypack.dev/-/esri-loader@v2.16.0-v8w89HETr1XbXBx1Bb9g/dist=es2019,mode=imports/optimize... which, by default, is set to the JS API V4.17.

I've tested using the setDefaultOptions() in the EsriLoader but it has no impact. I believe this is because the React -arcgis library is controlling this (and would explain why we're seeing an older version loaded), and we can't reach those options.

Working around the react-arcgis Scene component and leveraging the EsriLoader directly does resolve this issue (as suggested in the git docs).

 

Thanks again,

 

Tom

RyanSutcliffe
Occasional Contributor II

Thanks, @TomThompsonEsriCA , @GavinRehkemper. I think the problem with the React-ArcGIS library using an older version of the ArcGIS API and not being overridable is a quirk of CodePen.io and the fact that it is using a pre-bundled cdn for the package. I tried to recreate the same Pen using CodeSandbox but that seemed to have trouble with the memory requirements of 3d scenes. 

So I've made a GitHub repo here with the above code. If you pull that and spin it up (`npm start`) you'll note that the version of the API is now correctly set to 4.20. You should also see an error in the console as per above. An additional error like this should also appear:


iframeConsoleRunner-d8236034cc3508e70b0763f2575a8bb5850f9aea541206ce56704c013047d712.js:1 [esri.views.LayerViewManager] Failed to create layerview for layer title:'no title', id:'17d2f3d6194-layer-3' of type 'base-elevation'. {layer: d, error: e}

 

(index):113 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'lastIndexOf')
at new a ((index):113)
at Function.a.getLogger ((index):117)
at (index):770


TomThompsonEsriCA
Esri Contributor

Further to this, In my test app, I loaded the v2.16 EsriLoader, without using any react classes or components, and the ExaggeratedElevationLayer is still working there. So this is not necessarily an issue with the older esriLoader version, or the older JS API version.

Sample app is here: https://codepen.io/tthompsonEsri/pen/XWayRqw?editors=0010

Seems specific to react classes, still trying to narrow it down.

 

Update:

Built out a custom component and passed it to the react Renderer(). It basically completely overlaps the React-arcgis.Scene component and does display the ExaggeratedElevation without issues. It's a lot of extra coding, but seems to work around the issue. 

https://codepen.io/tthompsonEsri/pen/VwzqNaX

 

Another Update:

 

Slightly more refined solution where the Scene in the child component is not overwriting the parent scene component.

https://codepen.io/tthompsonEsri/pen/mdMoWwL?editors=0010

A CodePen implication of the 'create-react-app' package. ...
RyanSutcliffe
Occasional Contributor II

Thanks for this Tom, I tested the last solution in your post and indeed that does the trick nicely. I'm not yet 100% sure what I garbled in my original example, I suspect the way the `getClass` function was returning the class was messing up the context of 'this'. 

In any case this works well and will fit my usage needs.

0 Kudos