I created my own custom Google Maps component using StencilJS to include in my Ionic project. The component works fine on android devices, however, it does not render on iOS devices. I cannot figure out the issue. I have tested it on both the iPhone emulator in xCode and on an actual iPhone device.
Below is the entire source code of my Stencil component:
import { Component, h, Prop, Host, Element, State, Watch, Event } from '@stencil/core';
import { EventEmitter } from '@stencil/core/internal';
import { Loader } from 'google-maps';
@Component({
tag: 'ba-google-map',
styleUrl: './google-map.component.css',
shadow: true,
})
export class GoogleMap {
@Element() el: HTMLElement;
@Event() markerSelected: EventEmitter;
@Prop({ attribute: 'api-key' }) apiKey: string;
@Prop({ attribute: 'map-center-lat' }) centerLat: number = 35.9606;
@Prop({ attribute: 'map-center-lon' }) centerLon: number = -83.9207;
@Prop({ attribute: 'map-zoom' }) zoom: number = 8;
@Prop({ attribute: 'map-pins' }) mapPins: Array<{
lat: number;
lng: number;
contentString?: string;
pinImgUrl?: string;
id?: number;
}>;
@Prop({ attribute: 'map-height' }) height: string = '40px';
@Prop({ attribute: 'map-disable-controls' }) disableControls: boolean = false;
@State() google;
@State() map: google.maps.Map;
@State() markers: google.maps.Marker[];
@Watch('mapPins')
handleMapPinChange() {
this.clearMarkers.call(this);
this.addMarkers.call(this);
}
componentWillLoad() {
this.initMap.call(this);
}
addMarkers() {
let markersTmp = [];
for (let pin of this.mapPins) {
const markerConfigOpts: {
position: object;
map: google.maps.Map;
icon?: string;
} = {
position: { lat: pin.lat, lng: pin.lng },
map: this.map,
};
if (pin.pinImgUrl) {
markerConfigOpts.icon = pin.pinImgUrl;
}
const marker = new this.google.maps.Marker(markerConfigOpts);
if (pin.contentString) {
const infoWin = new this.google.maps.InfoWindow({
content: pin.contentString,
});
marker.addListener('click', () => {
infoWin.open(this.map, marker);
this.markerSelected.emit(pin);
});
}
markersTmp.push(marker);
}
this.markers = markersTmp;
}
clearMarkers() {
for (let i = 0; i < this.markers.length; i++) {
this.markers[i].setMap(null);
}
this.markers = [];
}
async initMap() {
if (!window['googleMapsLoader']) {
window['googleMapsLoader'] = new Loader(this.apiKey);
}
this.google = await window['googleMapsLoader'].load();
let mapConfigOpts: {
center: object;
zoom: number;
zoomControl?: boolean;
mapTypeControl?: boolean;
scaleControl?: boolean;
streetViewControl?: boolean;
rotateControl?: boolean;
fullscreenControl?: boolean;
} = {
center: { lat: this.centerLat, lng: this.centerLon },
zoom: this.zoom,
};
if (this.disableControls) {
mapConfigOpts.zoomControl = false;
mapConfigOpts.mapTypeControl = false;
mapConfigOpts.scaleControl = false;
mapConfigOpts.streetViewControl = false;
mapConfigOpts.rotateControl = false;
mapConfigOpts.fullscreenControl = false;
}
this.map = new this.google.maps.Map(this.el.shadowRoot.querySelector('#map') as HTMLElement, mapConfigOpts);
(this.el.shadowRoot.querySelector(`#map`) as HTMLElement).style.height = this.height;
this.mapPins && this.addMarkers.call(this);
}
render() {
return (
<Host>
<div id="map"></div>
</Host>
);
}
}
Below is the CSS file for the component (if needed...there is not much here):
#map {
width: 100%;
background: #eee;
}