Can you access a portalIems tags from a WebMap before loading the item.

1061
6
12-03-2020 02:02 PM
Freiberg
New Contributor II

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.

0 Kudos
6 Replies
Freiberg
New Contributor II

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?

0 Kudos
ChristianBischof
Esri Contributor

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.

PortalItem | ArcGIS API for JavaScript 4.17

0 Kudos
Freiberg
New Contributor II

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

0 Kudos
ChristianBischof
Esri Contributor

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.

 

Freiberg
New Contributor II

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.

ChristianBischof
Esri Contributor

You're welcome, allways a pleasure to help each other - nice solution with the tags!

0 Kudos