I am trying to sort WebMaps layers by their portalItems tags before loading them. My goal is to be able to sort layers into groups and create a UI element where users choose to display a feature layer based on its tag before loading the layer. Here is the code that I am running.
var webmap = new WebMap({
portalItem: {
id: webmapId,
portal: portalObject,
},
}).load().then(function(tmp_map){
for(const layer of tmp_map.allLayers.items) {
if (layer.type == "feature"){
console.log("loading " + layer.title)
console.log(layer.portalItem.tags)
new FeatureLayer({...layer,
portal: portalObject,
}).load().then(feature_layer => {
feature_layer.visible = true
map.add(feature_layer)
console.log("loaded " + feature_layer.title)
console.log(feature_layer.portalItem.tags)
});
break;
}
};
});
The first two console logs output null for the tags
loading Original Design DSM Layout
null
The second two console logs output the tags as an array of strings as expected
loaded Original Design DSM Layout
Array(4) [ "TEMP", "8022", "TI", "Geotechnical Construction" ]
When looking at the request you can see that when loading the WebMap each layer gets this data:
id
layerType
url
visibility
opacity
title
itemId
showLegend
Is there a way to load the tags alongside these when loading a WebMap.
I've now tried to get all the portalItems themselves without the layer to reduce load times and it significantly reduces load times but loading 250 portalItem just for the tags is still slow.
function getTag (layer){
if (!layer.portalItem){
return null;
}
var tag = new PortalItem({
id: layer.portalItem.id,
portal: portalObject
}).load().then(function(){
console.log(tag.tags)
});
return tag
}
Is there a way to batch get portalItems or batch get layers to reduce the number of requests and hopefully speed up the whole process?
Maybe you could use the fetchData() Promise from the PortalItem Class instead of the load() Promise you are using right now. You can specify the responseType there. I guess if you choose JSON for example you could possibly reduce workload for fetching the data and speed up your process.
This idea looks promising to me but I am unsure how to use the fetchData method. Currently, when I use it with just the parameter "json" the response is null. I suspect I need to pass in the options object to let the fetchData method know more specifically what data I am looking for. Do you have an example of what this options object is meant to look like or able to link me some documentation explaining the options object?
Thanks
Maybe you are treating it the wrong way as it is technically not a JS function, but a Promise.
Here is the Doc to the fetchData Promise:
PortalItem | ArcGIS API for JavaScript 4.17
Promise - JavaScript | MDN (mozilla.org)
You can try the logic of the code sample below:
let testPortalItem = new PortalItem({
id: "af1ad38816814b7eba3fe74a3b84412d"
});
let responseData = testPortalItem.load().then((response) => {
console.log(response);
response.fetchData().then((meep) => { console.log(meep)} ).catch((err) => { console.log(err) })
}).catch(error => {
console.log(error);
});
the default value of fetchData() is json.
Thanks for the help, I did get this method working similar to they way you listed here but in the end I couldn't find the correct information I was looking for with the fetchData method.
I ended up going through all the layers that were on my webmap and applying tags to them manually and now I can query them easily enough and this does exactly what I was hoping.
function createQuery(query, title, index, map_collapse, map){
let searchString = "tags:'" + map.project + "' AND tags:'" + map.tag + "' AND tags:'" + tag + "'"
var query = {
query: searchString,
sortOrder: "asc",
sortField:"title",
num: 300
};
var array = []
portalObject.queryItems(query).then(response =>{
response.results.forEach((portalItem) => {
layer = createLayerFromPortalItem(portalItem);
array.push(layer)
});
map.layers[index] = array;
})
}
Thanks again for the help.
You're welcome, allways a pleasure to help each other - nice solution with the tags!