2

I'm having problems getting Google's Place Autocomplete Address Form to work in a Blazor Web Assembly app.

I'm using Google's documentation https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete-addressform

I include the JavaScript at the bottom of index.html. I have a js file that contains JavaScript per the documentation and I'm including the Places library from Google API.

<script src="js/googleAddressAutocomplete.js"></script>    
<script
    src="https://maps.googleapis.com/maps/api/js?key={MyApiKey}&callback=initAutocomplete&libraries=places&v=weekly"
    defer
></script>

In the Blazor component, I'm using the same markup as the documentation.

<div id="locationField">
    <input
        id="autocomplete"
        placeholder="Enter your address"
        onFocus="@GeoLocate()"
        type="text"/>
</div>

Except I'm calling a C# method which using JS Interop to call the Geolocate function.

private async Task GeoLocate()
{
    await JSRuntime.GeoLocate();
}

When I run it, I get this error in the console: InvalidValueError: not an instance of HTMLInputElement

Looks like it can't find the input element, but I don't understand why. And I don't know what to do about it. I'm using the same code from Google's documentation, but migrating it to Blazor WASM. Can someone point me in the right direction? thanks, Dave

Jakob Em
  • 1,032
  • 9
  • 19
  • I'm confused about your `await JSRuntime.GeoLocate()` line. Are you trying to call a JavaScript function from your C# code? Per the [official docs](https://learn.microsoft.com/en-us/aspnet/core/blazor/call-javascript-from-dotnet?view=aspnetcore-5.0) I'd expect you to be using `.InvokeVoidAsync` or `.InvokeAsync`... or is your `JSRuntime.GeoLocate();` a call out to a custom method you wrote in another file that handles the `.Invoke` call? Aside from that, I can't spot anything out of the ordinary. – JeremyW Nov 11 '20 at 01:26
  • Per the docs you linked (thanks for that)... when are you calling the JS function `initAutocomplete()`? That's where the library identifies the HTML element it targets... if the input tag isn't in the DOM when `initAutocomplete()` is run, subsequent calls to the library's `geolocate()` method will fail. – JeremyW Nov 11 '20 at 01:32
  • I'm using extensions methods for JSRuntime. I've verified that the function is being called. – David Evans Nov 11 '20 at 01:34
  • Thanks. I kind of figured it was something like that, but I'm not sure how to delay the call to initAutocomplete() in Blazor. Actually, it's Google's Places JS library that is calling it. I only see the call to the Geolocate function. – David Evans Nov 11 '20 at 01:39
  • Sounds like it, delay it until after your component renders. A couple minutes of google searching for stuff like *blazor script tag in component* produces a couple promising leads... [(1)](https://stackoverflow.com/questions/58976579/blazor-server-load-js-scripts-only-on-certain-pages-not-on-all) [(2)](https://www.meziantou.net/javascript-isolation-in-blazor-components.htm) though it isn't something I've done before. Good luck! – JeremyW Nov 11 '20 at 01:47
  • I believe the new .NET 5 actually allows for isolating JavaScript for a single Blazor component without any workarounds. I was planning on upgrading anyway so I will try that. Thanks for your help. – David Evans Nov 11 '20 at 02:10

0 Answers0