GoogleWebComponents / google-apis

Web components for loading Google's JavaScript Libraries
https://elements.polymer-project.org/elements/google-apis
Other
87 stars 64 forks source link

Google Maps API multiple times error with Angular 2 #67

Open robisim74 opened 8 years ago

robisim74 commented 8 years ago

Hi,

I am trying to use google-map element with Angular 2: the display is correct, and all the google-map properties work well, but the properties of google-maps-api. For example:

<google-map api-key="AIzaSyCqrVHpM_zlUEPtxJPQiFYIqwfKcOctB_M" language="en" latitude="37.77493" longitude="-122.41942"></google-map>

I see the following error twice, once for each property that belongs to the google-maps-api (language and api-key):

You have included the Google Maps API multiple times on this page. This may cause unexpected errors.

In fact, in the browser Sources, I see three loads of Google Maps Api: one with no parameters, one with the API key and finally one with the API key and the language.

If I set directly into the google-map the properties, the error does not occur:

<google-maps-api id="api" api-key="AIzaSyCqrVHpM_zlUEPtxJPQiFYIqwfKcOctB_M" client-id="[[clientId]]" version="[[version]]" signed-in="[[signedIn]]" language="en" on-api-load="_mapApiLoaded"></google-maps-api>

I have seen that this error occurs in other cases, such as: #22

Is there an explanation? Thanks.

ebidel commented 8 years ago

Please provide full jsbin that repos the issue.

On Fri, Feb 12, 2016, 4:36 PM Roberto Simonetti notifications@github.com wrote:

Hi,

I am trying to use google-map element with Angular 2: the display is correct, and all the google-map properties work well, but the properties of google-maps-api. For example:

<google-map api-key="AIzaSyCqrVHpM_zlUEPtxJPQiFYIqwfKcOctB_M" language="en" latitude="37.77493" longitude="-122.41942">

I see the following error twice, once for each property that belongs to the google-maps-api (language and api-key):

You have included the Google Maps API multiple times on this page. This may cause unexpected errors.

In fact, in the browser Sources, I see three loads of Google Maps Api: one with no parameters, one with the API key and finally one with the API key and the language.

If I set directly into the google-map the properties, the error does not occur:

<google-maps-api id="api" api-key="AIzaSyCqrVHpM_zlUEPtxJPQiFYIqwfKcOctB_M" client-id="[[clientId]]" version="[[version]]" signed-in="[[signedIn]]" language="en" on-api-load="_mapApiLoaded">

I have seen that this error occurs in other cases, such as: #22 https://github.com/GoogleWebComponents/google-apis/issues/22

Is there an explanation? Thanks.

— Reply to this email directly or view it on GitHub https://github.com/GoogleWebComponents/google-apis/issues/67.

robisim74 commented 8 years ago

Hi @ebidel,

I have included here an essential example.

Thanks.

ebidel commented 8 years ago

Not sure exactly what's going on here, but you described the underlying problem. The Google Maps API throws these warnings when the API is loaded more than once.

I'm not seeing where google-maps-api is used in your code. The google-map element uses google-maps-api to load the JS API code. If it's used again with different parameters, you'll get the console warnings. But you should never really need use you google-maps-api directly.

robisim74 commented 8 years ago

In fact, the google-maps-api element is used only once through the google-map. But the request of the JS API is made for each property. So I have no other solution than building a custom element with the properties already set?

ebidel commented 8 years ago

That's correct. Because of how the Maps API loads, it's important to have all your properties known ahead of time, before creating <google-map>. If you change them at runtime, google-map will try to load a new version of the library url, but it will fail because Maps doesn't support multiple loads (with changed params). If you don't know all your params at setup time, use a template to delay the load:

<template is="dom-if" if="[[loadMaps]]">
  <google-map ...>...
</template>
robisim74 commented 8 years ago

I'm sorry @ebidel , but I don't want to change the params at runtime, I would just like to understand why this simple use of google-map: <google-map api-key="AIzaSyCqrVHpM_zlUEPtxJPQiFYIqwfKcOctB_M" language="en" latitude="37.77493" longitude="-122.41942"></google-map> as in the example causes the Google Maps API multiple times error.

ebidel commented 8 years ago

It doesn't: http://jsbin.com/tipemoseka/edit?html,output

robisim74 commented 8 years ago

Yes, it does. As I said, the error occurs if it is used with Angular 2. Thanks anyway.

nooruddinabbas commented 8 years ago

This is an old post and hopefully you have resolved this. I ran in to an issue that might just be related. Seems like if you import the GOOGLE_MAPS_PROVIDERS in more than one location it gives you this issue. So its better to add it to bootstrap once. The following forum helped me solve my problem:

https://github.com/SebastianM/angular2-google-maps/issues/315

robisim74 commented 8 years ago

Hi @nooruddinabbas,

thanks for your interest, but I haven't solved the problem of coexistence between Angular 2 and Polymer google-maps-api, and I decided to create custom components in Angular 2, just like angular2-google-maps library.

Greetings

edclement commented 8 years ago

Yeah, I'm running into this same exact issue when trying to use Angular2 :+1:

edclement commented 8 years ago

And I just have to add, I find it kind of ridiculous that google's polymer components aren't playing nicely with google's angular2. How long has angular2 been in development now?....

Splaktar commented 8 years ago

We were hoping to use the Polymer Google Map in our Angular 2 application as well. But due to this blocking (and closed) issue, we'll have to use https://github.com/SebastianM/angular2-google-maps instead.

This issue may need to be re-opened against the Polymer element itself https://github.com/GoogleWebComponents/google-map/issues since this is not really resolved.

ebidel commented 8 years ago

It looks like Angular is doing something interesting under the hood. Does anyone know more about the internals of how component markup is parsed and setup in Angular2? Seems like it strips attributes and re-adds them? I see 3 requests being made to the Maps API loader:

https://maps.googleapis.com/maps/api/js?callback=https___maps_googleapis_com_maps_api_js_callback___callback___v_3_exp_libraries_drawing_geometry_places_visualization_api_loaded&v=3.exp&libraries=drawing,geometry,places,visualization

https://maps.googleapis.com/maps/api/js?callback=https___maps_googleapis_com_maps_api_js_callback___callback___v_3_exp_libraries_drawing_geometry_places_visualization_key_AIzaSyCqrVHpM_zlUEPtxJPQiFYIqwfKcOctB_M_api_loaded&v=3.exp&libraries=drawing,geometry,places,visualization&key=AIzaSyCqrVHpM_zlUEPtxJPQiFYIqwfKcOctB_M

https://maps.googleapis.com/maps/api/js?callback=https___maps_googleapis_com_maps_api_js_callback___callback___v_3_exp_libraries_drawing_geometry_places_visualization_key_AIzaSyCqrVHpM_zlUEPtxJPQiFYIqwfKcOctB_M_language_en_api_loaded&v=3.exp&libraries=drawing,geometry,places,visualization&key=AIzaSyCqrVHpM_zlUEPtxJPQiFYIqwfKcOctB_M&language=en

Each time an attribute is being added, but the original code has all three at instance time.

Compare this to the jsbin I posted that doesn't use Angular. One call is made with all 3 attributes.

cc @robdodson

robdodson commented 8 years ago

+@robwormald

ebidel commented 8 years ago

I think we understand what's happening now. Angular's bootstrap reconstructs the DOM from the string template. This means the attributes are actually "removed" then added one by one:

http://i.imgur.com/4b98YFd.png

Hence, the multiple loads of the library, each adding a new parameter. To guard against this, the loading code can probably use a debouncer or be smarter about not making additional calls. Also, it would be worth removing observers for things like clientId/apiKey/version after they've been set the first time. One of the problems here is that we're observing changes to those properties in the first place. After initial load, it doesn't make sense to be able to update those values. Doing so leads to weird errors like this with the Maps API.

Splaktar commented 8 years ago

The debouncer and removing observers after they are set both sound like great ideas that would benefit Angular 2 users and others in the future. Thanks for taking another look at this @ebidel!

MrChoclate commented 8 years ago

Is there any workaround?

Splaktar commented 8 years ago

@MrChoclate we are happy with angular2-google-maps (mentioned here https://github.com/GoogleWebComponents/google-apis/issues/67#issuecomment-234790151) for now.

robdodson commented 8 years ago

If I recall @ebidel fixed this?

ebidel commented 8 years ago

Not yet :\ Given the info in https://github.com/GoogleWebComponents/google-apis/issues/67#issuecomment-235036574, it would be awesome if someone wants to propose a PR that would be cool.