In Angular code snippet from a known example, not recognized layer.sublayers. Why and what is wrong?
const layer= new WMSLayer({url: "my url"});
const precipitation = layer.allSublayers.find((sl) => sl.name === "example name");
layer.sublayers = [precipitation];
In code exist
import { AppConfiguration } from "read-appsettings-json";
import esriConfig from "@arcgis/core/config";
import WMSLayer from '@arcgis/core/layers/WMSLayer';
import Map from '@arcgis/core/Map';
import SceneView from '@arcgis/core/views/SceneView';
import Bookmark from "@arcgis/core/webmap/Bookmark";
import Bookmarks from "@arcgis/core/widgets/Bookmarks";
import Expand from "@arcgis/core/widgets/Expand";
import WMSSublayer from "@arcgis/core/layers/support/WMSSublayer";
Does anyone know the answer to this question? Please respond!
Hi @DimaY
Looking at the snippets you provide, I assume the issue might not be related to Angular implementation but rather to how the code deals with the layer and its sublayers. Here are some initial thoughts:
Do you only need the precipitation layer from the WMS service? In this case, you could already filter that out when creating the WMSLayer:
const layer = new WMSLayer({
url: "https://ows.terrestris.de/osm/service"
sublayers: [
{
name: "TOPO-OSM-WMS"
}
]
});
Here’s a simple sample app: https://codepen.io/gsoosalu/pen/poVzyPK
If you do need all the sublayers in the beginning, the problem could be that you call layer.allSublayers too early and the layer is not yet loaded. To fix this, try the following instead (though, you cannot use this to overwrite the layer.sublayers😞
let mySublayer;
layer.when(() => {
mySublayer = layer.allSublayers.find((sublayer) => sublayer.name === "TOPO-OSM-WMS");
});
Hope this helps you a bit further.
If not, could you explain a bit more what you need or provide a simple codepen example with an application where it occurs?
Hmm ... :)) So in the example above in the code (and by the way this code is taken from here from the example site) you can see what I need and what I ask. Well, OK. No, I do not need to initially initialize and put a layer with a name. Otherwise, why should I search for all layers and then try to change it by searching by name? I just need to define a WMSLayer object, specify all layers in a separate element and change the map itself by the layer selection event, that is, give a layer to this object as shown in the example above. But it doesn't work in Angular. For some reason he does not understand this property like this const precipitation = layer.allSublayers.find((sl) => sl.name === "example name");
layer.sublayers = [precipitation];
"example name" - this is what I chose from the list in the course of my action. Not what I originally wrote! I hope with my bad English I explained myself clearly.
const layer = new WMSLayer({ url: "https://ows.terrestris.de/osm/service" sublayers: [ { name: "TOPO-OSM-WMS" } ] });
If I had originally written like this, then I would not have received a list of all possible layers. And I would have received only the one determined by me! Then what's the point of searching by name and giving it a layer again? That's the trick and it is indicated in the question that initially I don't know which map and layer the user will choose. And on his choice, set the layer by name. But it turns out to be practically impossible! Although this is shown in the example on the site. Why show something that initially can not work?
Thanks a lot!
Sorry, I don’t really understand how if it is written in the example on this site, this is ...
layer.sublayers = [precipitation];
But at the same time you say that it is impossible to do. Or is it just not supported in Angular? But it's the same html and javascript. No?
https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-WMSSublayer.html
here is an example of what I tried to explain without success.
const layer = new WMSLayer({ url: "https://public-wms.met.no/verportal/verportal.map?request=GetCapabilities&service=WMS&version=1.3.0" });
await layer.load();
const precipitation = layer.allSublayers.find((sl) => sl.name === "precipitation_3h_global");
layer.sublayers = [precipitation];
const timeDimension = precipitation.dimensions.find((dimension) => dimension.name === "time");
Hi @DimaY
Thanks for the further explanations! If I understand it correctly now, you want to save a list of all available sublayers and allow to make one of them visible when searching for its name. For that, I recommend to work with the sublayer visibility.
The following sample app shows how to use a dropdown to select which WMSLayer sublayer is currently visible: https://codepen.io/gsoosalu/pen/bGMNveY
Note: you wouldn't want to overwrite the WMSLayer.sublayers if you still want use any of other sublayers again (without calling the service again).
Hope this helps you further. Let me know if you run into any further issues.
Thank you very much for your attention and your response. This is a very good idea! But... In code to make just visible true to Sublayer, every time you need to run through the cycle of all layers and look for it by name. Which is very very slow, long and inefficient. Really much easier just to change sublayers for WMSLayer. I saw code examples here as I wrote above, but he does not want to be friends with angular. If it were easy, I wouldn't be posting on the forum. Possible get out to come up with all sorts of tricks, write additional services and assign WMSLayer with new sublayers by selected Name. But there is no beautiful and optimal solution yet. Only everything topsy-turvy. Despite the fact that properties exist and they can be controlled in some way. But there is no explanation. Unfortunately.
<calcite-dropdown> </calcite-dropdow>
You have a closing tag with an error in the example <calcite-dropdown> </calcite-dropdow>