Search code examples
polymergoogle-maps-markersweb-componentgoogle-web-component

google-map-marker in dom-repeat has binding issue


i'm trying to make a polymer page with a map, in the map i'm trying to put multiple markers (easy with a dom-repeat), when i click a marker i want to show an infowindow with a component inside that accepts data from outside and displays it in some way. I'm currently having an issue trying to make the dom-repeat of the google-map-marker with binding of the information passed to the component inside the infowindow.

Basically when dom-repeat is executed and the markers created the data is correctly set in the infowindow component, but somewhere between then and when you show the infowindow the data is lost and all that was set is now undefined.

I've tried different things and the conclusions are these:

Binding works if used with a

<slot></slot>

tag, displaying the content directly.

Infowindow component code:

<dom-module id="report-infowindow">
    <template>

        <paper-button><slot></slot></paper-button>

    </template>
    <script>
        /**
         * @customElement
         * @polymer
         */
        class ReportInfoWindow extends Polymer.Element {
            static get is() {
                return 'report-infowindow';
            }

            static get properties() {
                return {
                    mproperty:{
                        type: String,
                        notify: true
                    }
                };
            }
        }

        window.customElements.define(ReportInfoWindow.is, ReportInfoWindow);
    </script>
</dom-module>

Page that calls the component

<dom-module id="map-page">
    <template>
        <style>

            :host {
                display: block;
            }

            google-map {
                width: 100%;
                height: 100%;
            }
        </style>

        <google-map fit-to-markers single-info-window="true" map="{{map}}" api-key="{{key}}">
            <template is="dom-repeat" items="{{markers}}">
                <google-map-marker slot="markers" map="{{map}}" latitude="{{item.lat}}" longitude="{{item.lng}}" draggable="false" icon="{{icon}}">
                    <report-infowindow>{{item.lat}}</report-infowindow>
                </google-map-marker>
            </template>
        </google-map>

    </template>

    <script>
        /**
         * @customElement
         * @polymer
         */
        class MapPage extends Polymer.Element {
            static get is() {
                return 'map-page';
            }

            static get properties() {
                return {
                    key: {
                        type: String,
                        value: "KEY"
                    },

                    icon: {
                        type: String,
                        value: "./src/assets/images/marker_small.png"
                    },

                    markers: {}
                };
            }
        }

        window.customElements.define(MapPage.is, MapPage);
    </script>
</dom-module>

Binding doesn't work if used with a property exposed by the component like this:

Infowindow component:

<dom-module id="report-infowindow">
    <template>

        <paper-button>{{mproperty}}</paper-button>

    </template>
    <script>
        /**
         * @customElement
         * @polymer
         */
        class ReportInfoWindow extends Polymer.Element {
            static get is() {
                return 'report-infowindow';
            }

            static get properties() {
                return {
                    mproperty:{
                        type: String,
                        notify: true
                    }
                };
            }
        }

        window.customElements.define(ReportInfoWindow.is, ReportInfoWindow);
    </script>
</dom-module>

Page calling the component:

<dom-module id="map-page">
    <template>
        <style>

            :host {
                display: block;
            }

            google-map {
                width: 100%;
                height: 100%;
            }
        </style>

        <google-map fit-to-markers single-info-window="true" map="{{map}}" api-key="{{key}}">
            <template is="dom-repeat" items="{{markers}}">
                <google-map-marker slot="markers" map="{{map}}" latitude="{{item.lat}}" longitude="{{item.lng}}" draggable="false" icon="{{icon}}">
                    <report-infowindow mproperty="{{item.lat}}"></report-infowindow>
                </google-map-marker>
            </template>
        </google-map>

    </template>

    <script>
        /**
         * @customElement
         * @polymer
         */
        class MapPage extends Polymer.Element {
            static get is() {
                return 'map-page';
            }

            static get properties() {
                return {
                    key: {
                        type: String,
                        value: "KEY"
                    },

                    icon: {
                        type: String,
                        value: "./src/assets/images/marker_small.png"
                    },

                    markers: {}
                };
            }
        }

        window.customElements.define(MapPage.is, MapPage);
    </script>
</dom-module>

But at the same time the property itself works if set with a static value like

<report-infowindow mproperty="sasa"></report-infowindow>

I don't understand if it's a bug or if it's something i'm doing wrong.

enter image description here


Solution

  • This is now fixed, but you must declare slot="markers" as an attribute of the google-map-marker component.

    <google-map fit-to-markers latitude="44" longitude="44" api-key="your_key">
      <template is="dom-repeat" items="[[data]]">
        <google-map-marker
          slot="markers"
          title="[[item.title]]"
          icon="marker.png"
          latitude="[[item.latitude]]"
          longitude="[[item.longitude]]">
        </google-map-marker>
      </template>
    </google-map>