Widget render function not behaving as expected?

06-14-2018 12:28 PM
New Contributor II

I'm trying to build a custom widget using the typescript setup as described in Create a custom widget | ArcGIS API for JavaScript 4.7.

Here's the essence of what the widget does:

1. User sees a map, and can click anywhere to add points.

2. Points are added to a local graphics collection, which is used as source for default layer.

3. That layer is passed to the widget, which then should render a list item for each feature in the collection.

The problem: My individual <li> elements are not rendering correctly.

In my widget code, I am using a private method to render the individual <li> items, although this seems unnecessary. (It also didn't work to render them directly inside the .map() method.)

Here's the code that seems to be giving me problems:

// Public method
     render() {
            return (
                         {this.layer.source.map((feature, index) => {
                              let item = this._renderItem(feature, index);
                              console.log('item', item)
                              return item;

     // Private method
     private _renderItem(feature, index): any {
          console.log('feature', feature.get('attributes'))
          return <li key={index}>{feature.get('attributes').name}</li>

If I console log "item" on line 8, it gives me an object like the following:

  "vnodeSelector": "li",
  "properties": {
    "key": 2
  "text": "test 3",
  "domNode": null

I am expecting a dom node instead. So my widget renders a <ul> filled with [object Object] strings. I'm not sure what I'm doing wrong. I tried to mimic the way that other widgets use .map() (for example in this one arcgis-js-api/Feature.tsx at 4master · Esri/arcgis-js-api · GitHub ).

I'll attach the whole app if anyone is interested in taking a look. Feeling kinda stuck. It's written in typescript. Run npm install and then run npm run dev to start the typescript compiler, then open index.html in a browser or host with something like http-server.

I'm still learning typescript, so there are some compiling errors, but I don't think that has anything to do with my problem.

Thank you to anyone who's read this far!

0 Kudos
1 Reply
Frequent Contributor

The source property of a layer is a Collection class in the JSAPI. It's like an Array, but with more bells and whistles.

FeatureLayer | API Reference | ArcGIS API for JavaScript 4.7 

In your case, you want to write your map like this.

      {this.layer.source.map((feature, index) => {
          let item = this._renderItem(feature, index);
          console.log('item', item)
          return item;

This will convert the collection of items to a normal array and it should render correctly.

The object you noted above is correct. The widget framework uses a virtual dom, objects that represent the DOM, not real DOM elements.