Mehigh17 / BlazorLeaflet

BlazorLeaflet is a Blazor component wrapping Leaflet's APIs, offering a simple and homogeneous implementation of the Leaflet maps.
MIT License
188 stars 91 forks source link

If not rendered before adding layers it will not accept new layers #25

Open erikthysell opened 4 years ago

erikthysell commented 4 years ago

There is an issue that if the map is not rendered before adding layers, layers[mapId] is not defined and hence cannot be pushed new layers onto. I assume this is because the create function is called in OnAfterRenderAsync method.

Mehigh17 commented 4 years ago

Could you please give a list of steps allowing to reproduce this issue?

sylvainonweb commented 3 years ago

Is there any news about this issue because it is really a big matter. Indeed, this arrives if I use the async version of OnInitializedAsync and OnAfterRenderAsync.

erikthysell commented 3 years ago

If the LeafletInterops.Create could be called in a LeafletMap.OnInitializedAsync method instead of in OnAfterRenderAsync I believe it could be averted but I am not sure if it can be done - my guess is that it can only be created on a html that is rendered...

sylvainonweb commented 3 years ago

In fact, the matter is the use of the Initialized event of the Map. Indeed, when you suscribe to this event, you are not sure that the OnInitializedAsync method has completed (so that your data are loaded and accessible).

To bypass this matter, I had to :

        public static void Initialize(Map map, float zoom = 12F, LatLng center = null)
        {
            map.Zoom = zoom;
            if (center != null)
            {
                map.Center = center;
            }

            // Init the map
            LeafletInterops.Create(this.JSRuntime, map);
            RaiseOnInitialized(); // Mandatory else AddLayer will throw an exception

            // Do default actions
            map.AddLayer(new OpenStreetMapsTileLayer());
            map.AddFullScreen();
            map.AddLocate();
        }

which permit me to do something like this

  protected override async Task OnInitializedAsync()
        {
            this.Data= LoadData();
            await base.OnInitializedAsyncEx();
        }

        protected override void OnAfterRenderEx(bool firstRender)
        {
            if (firstRender)
            {
                this.Map.Initialize(12F);
            }
            else
            {
                if (this.OnInitializedAsyncCompleted)
                {
                    this.Map.RemoveMarkers();

                    this.Map.PanTo(new PointF(Data.X, Data.Y););
                    this.Map.AddMarker(
                        wgs84Point,
                        new Tooltip { Content = Data.Text },
                        null,
                        new Icon { Url = "XXXX" });
                }
            }

            base.OnAfterRender(firstRender);
        }