Widget render function not behaving as expected?

641
1
06-14-2018 12:28 PM
AndyZeigert
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 (
               <div>
                    <ul>
                         {this.layer.source.map((feature, index) => {
                              let item = this._renderItem(feature, index);
                              console.log('item', item)
                              return item;
                         })}
                    </ul>
               </div>
          );
     }

     // 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
ReneRubalcava
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.

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

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.