Places autocomplete (javascript) has been weird in a lot of ways. I'm to the point that it works seemingly all the time on certain browsers, but intermittently on others. And to get here I've had to do some things counter to other advice, (though the 'correct' way works even less) so I have a lot to list.
The specific issue (on any browser) is that the callback initAutocomplete() does fully occur, but sometimes the input field just doesn't get the suggestions appearing. There are, however, no errors logged. I've found 2 things of note when it fails: pac-container is not created, and no requests are sent for AutocompletionService.GetPredictions.
The errors does not seem to ever occur on FireFox or on Edge. It happens most of the time on Chrome. It never works on iOS Chrome but does rarely on Safari... Not a useful pattern, so far.
There is more than one call to Maps APIs on the page, causing the "You have included the Google Maps JavaScript API multiple times on this page. This may cause unexpected errors." error. However, there does not seem to be an actual problem from this as the calls are to different libraries (geometry and places). And the callback function of the place script absolutely always functions, at least.
Aside from that, no errors of any kind report. It is notable that I'm currently attaching a sessiontoken that is actually session based (for the user, so for multiple requests.) This is directly contrary to information such as stackoverflow.com/a/50452233/5140781 (I've searched a lot before posting) that says a sessiontoken is not needed and will be handled automatically. It is contrary because not including it makes the service break far more often. Without it it breaks a good amount of the time on Firefox and Edge which are currently fine and Chrome will only work once per user session, after one refresh or on any subsequent form it is definitely not going to work any more. I've also tried attaching a random session token on every page load, that didn't help either. Though since in all cases the error is fairly random it could be that the error has nothing to do with the session token and everything I've seen is just human pattern seeking and [bad] luck. Maybe it is just a race condition of the different API calls for all I know. I get it to work on Chrome more if I do a 'empty cache and hard reload' than just F5; add that to it typically working the first time in a session and maybe you have that loading the scripts from cache is more likely to cause an issue than when they load for real? I'm out of ideas, or at least ones I think are reasonable.
The code for the initAutocomplete is almost exactly as given in the example, save adding the sessiontoken (and again, without that it fails more).
Any help would be appreciated.
It was, in fact, the double inclusion of a google API. This is despite the fact one include library was geometry and this was places, and that the callback on the Place script was happening even in fail states..
Simply removing the geometry include on the relevant pages fixed the Autocomplete functionality 100% (and we could drop the sessiontoken), but geometry was needed for other functions on the page. That was solved by adding it to the include made for the place library. Simply use commas to target multiple libraries; I didn't see that mentioned in the documentation, but is was an easy guess:
<script src="https://maps.googleapis.com/maps/api/js?key=********&libraries=places,geometry&callback=initAutocomplete" async defer></script>
Now, if you need geometry (or whatever other library) higher and sooner than your place include, that is a new problem I did not have. But for anyone finding this, my most simple recommendation would be moving the whole autocomplete chunk up there and combining the include in the same way. There are then 2 possible issues: The other script already having a callback, and the form potentially not existing yet.
The callbacks can be combined trivially if only the first point is your issue; just do the other callback code then the autocomplete. For just the second, there are two options: First, if you can have your form appearing trigger an event, then have the callback set a listener for it to then to its usual (watch for the form possibly loading first though!). Second, a setInterval that checks for the element existing and does the work when it is found (and stops checking)--that is dirty, but will work with just vanilla js; there is probably a better option if whatever framework you have. If you have both problems, just have the listener/interval at the start of the callback.