Hi all,
I'm trying to hit the properties of the sublayers in a map image service using the "allSublayers" property of that service. It works fine in the console in Chrome:
I can hit each of these items and access the properties of each:
But when I try to hit the same in code, using the same syntax, but targeting a new MapLayer object that's being added to the map, I can only see up to the array of sublayers itself, and not access any of the records in that array, nor the properties of any of those records:
Looking for the items array
the returned items array
looking for the first record in that array
"undefined"
Any ideas? Is this some bug or something?
Thanks!
Solved! Go to Solution.
Brain,
Here is how to ensure the layer is loaded and get access to a particular sub layer:
watchUtils.when(mapLayer, "loaded", function(){
mapLayer.findSublayerById(e.target.layerId).visible = e.target.checked;
mapLayer.refresh();
});
Brain,
Are you checking to see if the "mapLayer" loaded property is true before you try and access the sublayers?
Robert,
That's what I expect that the issue is as well, but I thought I was handling that correctly. I use a .when to wait until the new esri/MapImageLayer is loaded (in the code below assigned to the variable "myLayer", before setting the visibility of the sublayer (line 102) whose ID (in the flattened set within the collection of the service) matches the id assigned to the check box (assigned on line 88). It could be that I'm misusing the "when" and the code is trying to access the allSublayers property before the layer is loaded, but shouldn't the allSubLayers array itself be inaccessible as well if the layer isn't loaded?
Anyway, thanks for your response. Here's the JS, CSS, and HTML for the app.
GitHub - BrianVanNostrand/JS_API_Test: Learning the Javascript API
Correction: mapLayer, not myLayer
Brain,
I am pretty confused by your workflow here. What exactly are you trying to do? Right now you are adding a MapImageLayer each time a checkbox is checked and setting the sublayer visibility for that particular sublayer id to true. Seems like a serious over kill to add a new MapImageLayer for each sublayer that is checked vs adding on MapImagelayer and setting the sublayer visibility for that one layer.
Robert,
You're right, I'm still trying to figure that part out. I plan on adding an if statement to catch the load state of the maplayer. The commented line //if (loadedURLs.includes(svcURL) == false){} will check if the URL of the new map layer already exists in an array that URLs are pushed to when map.add is called and only add a new map layer when that URL hasn't already been pushed to that array. It's an imperfect solution that I plan on improving later, but for now it's the best I have come up with. I'd love to hear a better solution, for sure.
Anyway, as far as I can tell, that shouldn't be preventing me from accessing the allSubLayers property in the code as its written. Again, I'm able to access the map layer properties and pull the array with the property "allSubLayers", but not hit the properties of those layers themselves. I could be wrong about this for sure, but it indicates to me that the layer has been loaded, at least enough that I should be able to access the properties of the allSubLayers array items.
I'm probably going about this all wrong but I thought I'd see if anyone has experience with the issue before I try other solutions. It's just really weird that I can get those properties in console but not in code...
Here's another example to illustrate the issue. In the first image, you'll see that I am logging the first index of the allSubLayers array, then the array itself (the highlighted lines). The second image shows what is returned. The browser interprets the selected index as null, whereas it finds the array fine. If you duplicate those console.log commands (third image) in the browser console itself, everything works great and it returns "true" for the visibility of index 0.
I think this is a fundamental javascript array functionality issue that none of the video tutorials I've watched have covered .
Any ideas?
img 1
img 2
img 3
Brain,
Here is how to ensure the layer is loaded and get access to a particular sub layer:
watchUtils.when(mapLayer, "loaded", function(){
mapLayer.findSublayerById(e.target.layerId).visible = e.target.checked;
mapLayer.refresh();
});
Thanks for this. I don't know why I keep seeing ".when" used on the map layer when it's initialized to wait for its load state, but your solution seems to work a lot better.
You could use the LayerList widget for this. It seems like it does what you are after.
Thanks Robert, but this is more of a learning exercise for me than a means to an end.