rungwiroon / BlazorGoogleMaps

Blazor interop for GoogleMap library
MIT License
319 stars 102 forks source link

TypeError: Cannot read properties of undefined (reading 'defaultView') #258

Closed BenBurge closed 1 year ago

BenBurge commented 1 year ago

BlazorGoogleMaps Version: 3.0.5

When trying to run the map logic with a marker I am getting the following error message:

TypeError: Cannot read properties of undefined (reading 'defaultView')

JS Stack Trace

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'defaultView')
    at new _.Pja (common.js:181:101)
    at Ew.j (map.js:130:672)
    at data.lg.map (js?key=REMOVED&v=3&libraries=places,visualization,drawing&callback=Function.prototype:211:199)

CaseMapView.razor

<div @ref="@ExampleMapReference" id="exampleMap" style="height: 450px"></div>

CaseMapView.razor.cs

using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using ServerClient.Shared;
using GoogleMapsComponents.Maps;

namespace ServerClient.Features.CaseMap
{
    public partial class CaseMapView : IDisposable
    {
        #region DI Properties
        [Inject]
        private IJSRuntime? JSRuntime { get; set; }

        [Inject]
        private ApplicationState? ApplicationState { get; set; }
        #endregion

        private Map? ExampleMap { get; set; }
        private ElementReference ExampleMapReference { get; set; }

        protected override async Task OnInitializedAsync()
        {
            if (JSRuntime == null) return;
            if (ApplicationState != null) ApplicationState.OnStateHasChanged += StateHasChanged;

            MapOptions mapOptions = new()
            {
                Zoom = 15,
                Center = new LatLngLiteral { Lat = 44.87816, Lng = -157.20785 },
                MapTypeId = MapTypeId.Roadmap
            };

            ExampleMap = await Map.CreateAsync(JSRuntime, ExampleMapReference, mapOptions);

            var newMakerOptions = new MarkerOptions()
            {
                Position = new LatLngLiteral { Lat = 44.87816, Lng = -157.20785 },
                Map = ExampleMap,
                Draggable = false,
                Icon = new Icon() { Url = "https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png" }

            };
            var createdMarker = await Marker.CreateAsync(JSRuntime, newMakerOptions);
            await createdMarker.SetMap(ExampleMap);
        }

        public void Dispose()
        {
            if (ApplicationState != null) ApplicationState.OnStateHasChanged -= StateHasChanged;
        }
    }
}

If I do this same thing on the Index component page I don't get this error message. The code is exactly the same on both pages so I am unsure what may be causing this JS exception. Let me know if I can give you any more details.

valentasm1 commented 1 year ago

I think it is impossible to load map on OnInitializedAsync (or at least there are some limitations). Maybe you could use some callback to achieve OnInitializedAsync initilizations. I think limitations comes from google maps itself since it could draw map while dom isnt rendered. Smth like that.

You should do at OnInitializedAsync on firstRender:true.

valentasm1 commented 1 year ago

If you look at GoogleMap (this library) implementation you will see that it is implement same way i reccomended OnAfterRenderAsync

BenBurge commented 1 year ago

Thank you! I will give that a try and see if I can get it working using after render.

BenBurge commented 1 year ago

That totally fixed my issue. Guess I should pay better attention to the lifecycle of Blazor and Javascript bits.

valentasm1 commented 1 year ago

No problem. I am always ready to help.