I have a simple logic working that I want to make a widget out of.
i have a problem implementing it inside the render() function.
the current state is i created the widget, and the individual functions work but once inside the are called dozens of times.
what is the correct way to call them from the render?
widget params:
---featurelayer - from drop down list chosen by the user. - the list created on widget start and updates when map changes(layers get added or removed).
---range -number - for querying the layer - from user
---enabled - boolean - is querying active? - changes on click
all this logic already works a quick overview of the four functions and watch:
---populateLayerList - creates feature layer List select
---onMapChange() function - calls populate function
watch for webmap changes and recreate dropdown list
---toggleQueryButton - true or false activates the view watch for user click on map and query the layer.
---executeQuery() - gets the params and adds graphic layer to the map
import Widget from "@arcgis/core/widgets/Widget";
import MapView from "@arcgis/core/views/MapView";
import WebMap from "@arcgis/core/WebMap";
import GraphicsLayer from "@arcgis/core/layers/GraphicsLayer";
import Graphic from "@arcgis/core/Graphic";
import { subclass, property } from "@arcgis/core/core/accessorSupport/decorators";
import { tsx } from "@arcgis/core/widgets/support/widget";
import FeatureLayer from "@arcgis/core/layers/FeatureLayer";
@subclass("esri.widgets.SimpleWidget")
class SimpleWidget extends Widget {
constructor(map: WebMap, mapView: MapView) {
super();
this.map = map;
this.view = mapView;
}
@property()
enabled: boolean = false
@property()
map: WebMap //| null = null
@property()
view: MapView //| null = null
render() {
let dropdown = this.populateLayerList()
this.onMapChange()
// widget container
// layer list to get all layers of the view - updates when change happens
// meter range for query
// execute button toggles on/of view.on click event that creates the query
//
return <div class="groundZeroWidget">
{dropdown}
<input id="queryRange" type="number" />
<button onclick={this.toggleQueryButton()}>execute</button>
</div>
}
//creates the list of feature layers on open and on change
private populateLayerList() {
console.log("populateLayerList");
let layerList: FeatureLayer[] = [] //list of all feature layers
this.map.allLayers.forEach((x: FeatureLayer) => {
if (x.type == "feature") {
console.log(x.title);
layerList.push(x) //list of layer titles
}
});
function MakeItem(x: FeatureLayer) {
return <option key={x}>{x.title}</option>;
};
return <select id="layerTitleList" >{layerList.map(MakeItem)}</select>;
}
private onMapChange() {
this.map.allLayers.on("change", function (event) {
console.log("onMapChange");
// change event fires after an item has been added, moved or removed from the collection.
// event.moved - an array of moved layers
// event.removed - an array of removed layers
// event.added returns an array of added layers
// this.populateLayerList() ----------not stable yet
})
}
// toggles widget active, changes button color
private toggleQueryButton() {
console.log('toggleQueryButton');
let layerList: __esri.Collection<FeatureLayer> | FeatureLayer[] = [] //list of all feature layers
this.map.allLayers.forEach((x: FeatureLayer) => {
if (x.type == "feature") {
layerList.push(x)
}
});
(this.enabled) ? (this.enabled = false) : (this.enabled = true) //toggles widget active
console.log("enabled?:" + this.enabled);
// change button color
this.view.on("click", (event) => {
console.log("click event: ", event.mapPoint);
let groundZeroXY = event.mapPoint;
if (this.enabled) {
this.executeQuery(groundZeroXY, layerList);
}
});
}
//when active creates layer from specifications and adds it to the map
private executeQuery(screenPoint: __esri.MapViewScreenPoint, layerList: any[] | __esri.Collection<FeatureLayer>) {
console.log("executeQuery");
//get selected layer
let layerTitle = (document.getElementById('layerTitleList') as HTMLSelectElement).value
console.log(layerTitle);
let queryLayer: FeatureLayer = layerList.find(x => x.title == layerTitle);
//get selected range
let range = (document.getElementById('queryRange') as HTMLInputElement).value;
console.log("range: " + range);
let Glayer = new GraphicsLayer();
let map = this.map
const point = this.view.toMap(screenPoint);
// Query the for the items within x-KM from where the user clicked for layer x
var query = queryLayer.createQuery();
query.geometry = point;
query.spatialRelationship = "intersects";
query.distance = parseInt(range);
query.units = "meters";
query.returnGeometry = true;
query.outFields = ["*"];
queryLayer.queryFeatures(query).then(function (res: __esri.FeatureSet) {
if (res.features.length === 0) {
console.log("no items 1st layer");
}
console.log(res.features);
console.log(res.features[0]);
let graphic: Graphic[] = res.features;
Glayer.addMany(graphic);
map.add(Glayer);
if (Glayer.graphics.length === 0) {
console.log("no featuers");
}
});
}
}
export = SimpleWidget;