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!
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.