Select to view content in your preferred language

Layer.fromPortalItem doesnt work when the portalitem id is a webmap

3391
6
Jump to solution
02-02-2017 08:39 AM
JasonRainwater
Deactivated User

Hi, we are trying to build a system that work with either ArcGIS server maps and ArcGIS online portal maps.  If I do Layer.fromPortalItem and the id I pass in is a webmap I get the following error.

[esri.layers.Layer] #fromPortalItem() Failed to create layer from portal item (portal: 'https://www.arcgis.com', id: 'myidhere') [portal:unknown-item-type]: Unknown item type 'Web Map'

Is there a way to query the web map as a layer that needs to be added to map just like we can do with Layer.fromArcGisServerUrl?

1 Solution

Accepted Solutions
KristianEkenes
Esri Regular Contributor

You can create a custom function using that workflow to get a collection of the layer item ids...

function getLayerIdsFromWebmap(webmapid){
  var webmap = new WebMap({
    portalItem: { // autocasts as new PortalItem()
      id: webmapid
    }
   });
 
  return webmap.load().then(function(){
    var layers = webmap.layers;
    return layers.map(function(layer){
      return layer.portalItem.id;
    });
  });
}
 
 getLayerIdsFromWebmap("f2e9b762544945f390ca4ac3671cfa72")
   .then(function(layerIds){
      console.log(layerIds);
 
      var firstLayerId = layerIds.getItemAt(0);
 
      return Layer.fromPortalItem({
        portalItem: {
          id: firstLayerId
        }
      });
   }).then(function(layer){
     view.map.add(layer);
 });

View solution in original post

0 Kudos
6 Replies
KristianEkenes
Esri Regular Contributor

I'm not entirely familiar with the other workflow you're using, but Layer.fromPortalItem() isn't designed to take a webmap id. It can only accept item ids of individual layers. To access individual layers of a webmap, you can add the webmap to your view and run the following:

view.then(function(){
 webmap.layers.forEach(function(layer, i){
   console.log("webmap layer ", i, ": ", layer);
 });
});

see the live sample here: JS Bin - Collaborative JavaScript Debugging 

Or call load() on the webmap outside the view:

webmap.load().then(function(){
 webmap.layers.forEach(function(layer, i){
   console.log("webmap layer ", i, ": ", layer);
 });
});
0 Kudos
JasonRainwater
Deactivated User

What I'm trying to do is control when the layers get loaded.  Is there a way to query a webmap for its layers and then use layer.fromPortalItem to actually get the layers?

0 Kudos
KristianEkenes
Esri Regular Contributor

In that case, you can use the workflow of the second snippet. Call load() on the webmap, this gets the layers in the webmap. Then you can call load() on individual layers to load them when you want in the app and add them to the map. Here's a test case: JS Bin - Collaborative JavaScript Debugging 

var webmap = new WebMap({
  portalItem: { // autocasts as new PortalItem()
    id: "f2e9b762544945f390ca4ac3671cfa72"
  }
});

var view = new MapView({
  map: new WebMap({
    basemap: "satellite"
  }),
  container: "viewDiv"
});
 
 webmap.load().then(function(){
   var layers = webmap.layers;
   var firstLayer = layers.getItemAt(0);
   console.log("first layer loaded? ", firstLayer.loaded);
 
   return firstLayer.load();
 }).then(function(layer){
   view.map.add(layer);
 });

You could also query a portal or a portalGroup, but it sounds like you really want the layers from a specific webmap. If that's the case, then you should use this workflow.

0 Kudos
JasonRainwater
Deactivated User

That is definitely closer and I might can make that work. Is there a way I can take a portalitem Id for a webmap and query to get the list of portal item Ids that are the layers and then use layer.fromPortalItem?

0 Kudos
KristianEkenes
Esri Regular Contributor

You can create a custom function using that workflow to get a collection of the layer item ids...

function getLayerIdsFromWebmap(webmapid){
  var webmap = new WebMap({
    portalItem: { // autocasts as new PortalItem()
      id: webmapid
    }
   });
 
  return webmap.load().then(function(){
    var layers = webmap.layers;
    return layers.map(function(layer){
      return layer.portalItem.id;
    });
  });
}
 
 getLayerIdsFromWebmap("f2e9b762544945f390ca4ac3671cfa72")
   .then(function(layerIds){
      console.log(layerIds);
 
      var firstLayerId = layerIds.getItemAt(0);
 
      return Layer.fromPortalItem({
        portalItem: {
          id: firstLayerId
        }
      });
   }).then(function(layer){
     view.map.add(layer);
 });
0 Kudos
JasonRainwater
Deactivated User

Awesome thanks Kristian!  Its a little weird but looks like it would work great for our purposes!

0 Kudos