I am developing an app in ExB that receives URL parameters and based on the parameters passed, it will select and zoom to the features in the map.
I have worked out how to get the map and layer datasources the map is using, but am unable to select features in the layer datasource. I am trying to call the selectRecordsById(string[]) method on the layer datasource but my unit testing shows that the selectRecordsById() method is not doing anything, I am passing it objectids (is this correct?). Am I on the right track?
Is there a sample somehwere that demonstrates the best practice for selecting features in a map from a custom widget?
Solved! Go to Solution.
This is how I select features in a DS.
const dsManager = DataSourceManager.getInstance()
const featureDS = dsManager.getDataSource(myDSId) as FeatureLayerDataSource
featureDS.query({objectIds:[ObjectId_Array]}).then(qr=>{
MessageManager.getInstance().publishMessage(
new DataRecordsSelectionChangeMessage(this.props.id, qr.records)
)
featureDS.selectRecordsByIds?.(qr.records.map((item) => item.getId()))
})
This is how I select features in a DS.
const dsManager = DataSourceManager.getInstance()
const featureDS = dsManager.getDataSource(myDSId) as FeatureLayerDataSource
featureDS.query({objectIds:[ObjectId_Array]}).then(qr=>{
MessageManager.getInstance().publishMessage(
new DataRecordsSelectionChangeMessage(this.props.id, qr.records)
)
featureDS.selectRecordsByIds?.(qr.records.map((item) => item.getId()))
})
Thanks for getting back to me Robert.
I have tried implementing something very similar to your sample in my code and it is still not working. I have debugged and think it has something to do with the lifecycle of the featureDS, its status is showing as unloaded and it has no records. I am deriving my datasourceID from the JimuMapView.dataSourceId and then getting a MapDataSource from the DataSourceManager, which I am then using mapDataSource.getDataSourceByLayer(layer id) to get a featureLayerDataSource using a nominated layerID. This is the datasource that is appearing unloaded. I have since added a load method with a where clause of 1=1 then run a query against the loaded featureLayerDataSource with the where clause for the selection. It seems to now perform the select (as the URL gets querystring parameters with the layer reference and objectid for the selected faeture) but the map widget is not showing the selected features. Am I on the right track? Why is the featureLayerDataSource in an unloaded state (especially since the layer is visble in the map widget)? Should I be doing something else to get the FeatureLayerDataSource into a loaded state?
Correction, I have found that the map is actually showing the selected feature. It seems as though the message action is failing to zoom on the map. The message seems to be getting through because the pan to action works, it just doesn't want to zoom to it. Is this a bug/known issue?
There is no bug that I am aware of.
Hey, I came across this thread when trying to work on a similar functionality, which is to highlight features in the built-in map widget. Calling selectRecordsByIds() doesn't seem to work in my code and the search lead me this thread. It's called in a useEffect() that watches the change of recordIds.
However, after I tried this code that includes publishing a message, I still don't see highlighted feature in my map widget. I can get correct data records from the query method though.
I have added the code below to check what records are selected and the result is an empty array. I also added publishMessages: ["DATA_RECORDS_SELECTION_CHANGE"] into manifest JSON, but not sure if I was doing the correct thing. Just wondering did I do anything wrong, e.g. anti-pattern coding? Any help or further questions will help.
widgetDS.selectRecordsByIds?.(qr.records.map((item) => item.getId()))
console.log('check ds selected records',widgetDS.getSelectedRecords())
@LoisLi @RobertScheitlin__GISP I am having the same issue. I am using functional components and maybe here is the issue why the above code does not work if its for class components? The query works but selectRecordsByIds() yields nothing and hence I get error extent invalid on the zoom to action. I suspect its something to do with the DataSource being Unloaded status. I have done the same as LoisLi, set up data source from settings.tsx, added publishgMessages to manifest JSON etc.
Finally got it working, despite terrible documentation.
selectRecordById() only worked when given FeatureDataRecord parameter, not only with objectId, contrary to what it states that FeatureDataRecord is optional. This fixed selection.
Then zoom and pan were not working due to invalid extent error. Adding returnGeometry: true to the query params has fixed this. Then published message worked to pan and zoom on the map widget to selected feature with message actions configured in settings. I can also see the feature being automatically selected in Table widget.
useEffect(() => {
if (selectedDynamicOption && selectedDynamicOption.length > 0 && dataSourceInstance) {
async function selectRecord() {
try {
const objectId = selectedDynamicOption[0].value;
dataSourceInstance.query({objectIds:[objectId], returnGeometry : true}).then(qr=>{
MessageManager.getInstance().publishMessage(
new DataRecordsSelectionChangeMessage(props.id, qr.records)
)
const fdr = qr.records[0] as FeatureDataRecord
dataSourceInstance.selectRecordById(objectId, fdr);
})
console.log('Record selected in data source.', dataSourceInstance.getSelectedRecordIds());
} catch (error) {
console.error('Error selecting record:', error);
}
};
selectRecord()
}
},[selectedDynamicOption]);