GoogleMaps API with Emberjs - javascript

I have a GoogleMap with EmberJs view. Everything works good except the data binding.
I want to bind the map markers with ember-data. If something changes at data level it must reflect on Map.
I tried to use observer, and re-run the makeMarkers method to set the marker, but that seems to be a bad solution.
What would be the best way to bind data with GoogleMaps?

View is deprecated on Ember 2.0, they will be removed at Ember 2.5, make a component like: {{g-map markers=models}}
This component have a collection of items, here markers.
You can implement something like this:
import Ember from 'ember';
import MarkerSync from '../mixin/marker-synchronizer';
/**
* Basic Component to display a google map,
* Service & Marker have to be improved
**/
export default Ember.Component.extend(MarkerSync, {
classNames: 'google-map',
googleMap: Ember.inject.service(),
map: null,
mapOptions: function () {
return {
center: new google.maps.LatLng(-34.397, 150.644),
zoom: 8
};
},
didInsertElement: function () {
this.$().height('100%');
this.$().width('100%');
this.displayGmap();
jQuery(window).on('resize', Ember.run.bind(this, this.handleResize));
},
willInsertElement: function () {
this.get('googleMap').loadScript();
},
displayGmap: Ember.observer('googleMap.isLoaded', function () {
if (!this.get('googleMap.isLoaded')) {
return;
}
const mapOptions = this.mapOptions();
this.set('map', new google.maps.Map(this.$()[0], mapOptions));
}),
handleResize: function () {
if (!this.get('googleMap.isLoaded')){
return;
}
const map = this.get('map');
const center = map.getCenter();
google.maps.event.trigger(map, 'resize');
map.setCenter(center);
},
});
import Ember from 'ember';
/**
* Synchronize collection with map from component.
* Care about to display or remove marker from map,
* Be careful this is not optimized.
**/
export
default Ember.Mixin.create({
markers: null,
_gHash: Ember.A(),
init() {
this._super.apply(this, arguments);
/*
* observes markers array.
*/
this.get('markers').addArrayObserver({
arrayWillChange: Ember.run.bind(this, this.markersWillChange),
arrayDidChange: Ember.run.bind(this, this.markersDidChange)
});
},
/*
* Remove marker from array and remove from map
*/
markerRemoved(marker) {
let gMarker = this.get('_gHash').find(function(item) {
return item.related === marker;
});
gMarker.native.setMap(null);
this.get('_gHash').removeObject(gMarker);
},
/*
* Add marker to `synchronized` array and display on map
*/
markerAdded(marker) {
const gMarker = new google.maps.Marker({
position: {
lat: marker.lat,
lng: marker.lng
},
title: marker.title,
map: this.get('map'),
});
this.get('_gHash').push({
native: gMarker,
related: marker
});
},
/*
* Take care about removed item
*/
markersWillChange(markers, start, removeCount, addCount) {
if (removeCount > 0) {
for (let i = start; i < start + removeCount; i++) {
this.markerRemoved(markers.objectAt(i));
}
}
},
/*
* Take care about added item
*/
markersDidChange(markers, start, removeCount, addCount) {
if (addCount > 0) {
for (let i = start; i < start + addCount; i++) {
this.markerAdded(markers.objectAt(i));
}
}
},
});
import Ember from 'ember';
const get = Ember.get;
/**
* This service lazy load googleMap api.
* Ugly but do the job
*/
export default Ember.Service.extend({
scriptUrl: 'https://maps.googleapis.com/maps/api/js',
isLoaded: Ember.computed.equal('state', 'loaded'),
state: 'none',
init: function () {
let config = this.container.lookupFactory('config:environment');
var apiKey = get(config, 'googleMap.apiKey');
this.set('apiKey', apiKey);
},
normalizeUrl: function () {
var url = this.get('scriptUrl');
url += '?' + 'v=3' + '&' + 'libraries=places' + '&' + 'callback=loadGmap';
if (this.get('apiKey')) {
url += '&key=' + this.get('apiKey');
}
return url;
},
loadScript: function () {
if (this.get('state') !== 'none'){
return false;
}
this.set('state', 'loading');
window.loadGmap = Ember.run.bind(this, function () {
this.set('state', 'loaded');
});
var url = this.normalizeUrl();
return Ember.$.getScript(url).fail(function(){
console.log('getScript fail');
});
},
});
This implementation work but you have to 'sanitize' this code :)

1) Create a component, not a view
2) Use didInsertElement to render google map and observer to update it. Don't forget that observers are synchronous (http://guides.emberjs.com/v1.13.0/object-model/observers/) and you need to do smth like:
somethingChanged: Ember.observer('something', function () {
Ember.run.once(this, '_somethingChanged');
}).on('init'),
_somethingChanged: function () {
/* do smth about changed property here */
}

Related

Leaflet-Map on Angular does not fit to the screen

Every time the Map is loading i am calling 500ms after finished the loading process the this.map.invalidateSize()-Method to try to clean the map view up.
But also when I am loading this, the map still appears like this:
What do i have to do, that the map loads directly in my location or at least in the defined center with the defined zoom-Level?
Is there any event, that I can listen for on Angular/Leaflet, which indicates, that the map has loaded properly and also the loaded KML-Data is loaded?
EDIT
The following code is producing this error. Please take note, that i have removed unused content, which is not relevant for this problem (like adding a marker to the map).
ngOnInit() {
this.initMap();
}
processBaseLayers() {
this.layerControl = L.control
.layers(this.layerControl, null, {
position: 'bottomright',
})
.addTo(this.map);
let defaultLayerSet = false;
this.baseLayers.forEach((layer) => {
const baseLayer = new L.TileLayer(layer.serverURL, {
maxZoom: layer.maxZoom,
attribution: layer.attribution,
});
if (!defaultLayerSet) {
baseLayer.addTo(this.map);
defaultLayerSet = true;
}
this.layerControl.addBaseLayer(baseLayer, layer.name);
});
}
fixMapOccurences() {
setTimeout(() => { this.map.invalidateSize() }, 500)
}
async initMap() {
this.map = L.map('map', {
center: [46.947222222222, 7.4441666666667],
zoom: 12,
zoomControl: false,
});
this.map.whenReady(() => {
this.processBaseLayers();
setTimeout(async () => {
this.fixMapOccurences();
await this.loadKML();
}, 1000)
});
}
async loadKML() {
this.dataLayers.forEach((dataLayer) => {
const kmlLayer = omnivore.kml(dataLayer.serverURL).on('ready', () => {
kmlLayer.eachLayer((layer) => {
if (layer.feature.geometry.type === 'Point') {
// adding point here
} else if (layer.feature.geometry.type === 'GeometryCollection') {
// adding polyline here
}
});
});
});
}

clearing markers after bounds changed, vue cookbook google map

I have an issue about clearing markers after updating new bounds. New markers get added to the map but old markers stay still. It's a bit awkward because Vuex state renews every time when I post a request with new bounds...
I am giving the references for better understanding
vue cookbook
and the cookbook's codesandbox (not my code but very much similar.)
map-loader.vue
Here I create the map and make request for bounds without a problem. And every time the map is dragged, I get the new markers in the new array in Vuex.
<template>
<div>
<div class="google-map" ref="googleMap"></div>
<template v-if="Boolean(this.google) && Boolean(this.map)">
<slot
:google="google"
:map="map"
/>
</template>
</div>
</template>
<script>
import GoogleMapsApiLoader from 'google-maps-api-loader'
import { mapGetters } from 'vuex'
export default {
props: {
mapConfig: Object,
apiKey: String,
info_and_center: Function,
},
data() {
return {
google: null,
map: null
}
},
async mounted() {
const googleMapApi = await GoogleMapsApiLoader({
apiKey: this.apiKey
})
this.google = googleMapApi
this.initializeMap()
},
watch:{
mapConfig(old_ad, new_ad){
this.initializeMap()
}
},
methods: {
initializeMap() {
const mapContainer = this.$refs.googleMap
this.map = new this.google.maps.Map(
mapContainer, this.mapConfig
)
let self = this;
this.google.maps.event.addListener((this.map), 'idle', function(event) {
self.get_markers();
});
},
get_markers(){
let bounds = this.map.getBounds();
let south_west = bounds.getSouthWest();
let north_east = bounds.getNorthEast();
let payload = {
"from_lat": south_west.lat(),
"to_lat": north_east.lat(),
"from_lng": south_west.lng(),
"to_lng": north_east.lng(),
}
// manually clearing the array of markers
this.$store.state.project.projects = []
console.log(this.get_projects)
// it's cleared
this.$store.dispatch("load_projects_by_coords", payload)
},
},
computed: {
...mapGetters([
"get_projects"
])
}
}
</script>
UPDATED
Normally I don't need to do that, but inside the get_markers() I wrote code to clear get_projects before new dispatch but still, old markers stay still.
map.vue
<template>
<GoogleMapLoader
:mapConfig="mapConfig"
apiKey="my_key"
>
<template slot-scope="{ google, map}">
<GoogleMapMarker
v-for="marker in get_projects"
:key="marker.id"
:marker="marker"
:google="google"
:map="map"
/>
</template>
</GoogleMapLoader>
</template>
<script>
import GoogleMapLoader from './google-map-loader'
import GoogleMapMarker from './google-map-marker'
import { mapSettings } from './helpers/map-setting'
import { mapGetters } from "vuex";
export default {
components: {
GoogleMapLoader,
GoogleMapMarker,
},
computed: {
...mapGetters([
"get_projects",
"get_search_address_lat",
"get_search_address_lng",
]),
mapConfig () {
return {
...mapSettings,
center: this.mapCenter
}
},
mapCenter () {
return {lat: this.get_search_address_lat, lng: this.get_search_address_lng}
},
},
}
As you see, I am iterating over the new markers inside the get_projects without any problem. But old markers stay still, although when I console.log(this.get_projects) only new markers are in there after the bounds have changed. So the question is How can I update the map with the new markers?
markers.vue
<script>
export default {
props: {
google: {
type: Object,
required: true
},
map: {
type: Object,
required: true
},
marker: {
type: Object,
required: true
},
},
mounted() {
let marker = new this.google.maps.Marker({
position: this.marker,
marker: this.marker,
map: this.map,
})
var contentString = "test";
var infowindow = new this.google.maps.InfoWindow({
content: contentString
});
this.google.maps.event.addListener(marker, 'click', function() {
this.map.setCenter(marker.getPosition());
infowindow.setContent(contentString);
infowindow.open(this.map, marker);
});
},
render(){},
}
</script>
I have not worked with this API before. But I see that removing markers is not covered in the cookbook link you posted. What I think is happening is that you are registering a new marker on mounted, which is fine of course, but you're not removing it when the component is destroyed.
The documentation says to use setMap on the Marker to null, in order to remove it. So maybe if you kept the reference to the marker created in the mounted hook, you can remove it in the beforeDestroy hook.
GoogleMapMarker.vue
data: () => ({
mapMarker: null
}),
mounted() {
const { Marker } = this.google.maps;
this.mapMarker = new Marker({
position: this.marker.position,
marker: this.marker,
map: this.map,
icon: POINT_MARKER_ICON_CONFIG
});
},
beforeDestroy() {
this.mapMarker.setMap(null);
},
ps. let self = this; is unnecessary.
let self = this;
this.google.maps.event.addListener((this.map), 'idle', function(event) {
self.get_markers();
});
Anonymous function:
this.google.maps.event.addListener((this.map), 'idle', event => {
this.get_markers();
});

Set Map bounds based on multiple marker Lng,Lat

Am using vue and have installed the vue-mapbox component located here: https://soal.github.io/vue-mapbox/#/quickstart
I have updated the js and css to the latest versions also that gets added to the index.html:
<!-- Mapbox GL CSS -->
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.51.0/mapbox-gl.css" rel="stylesheet" />
<!-- Mapbox GL JS -->
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v0.51.0/mapbox-gl.js"></script>
I am trying to utilize this component to set the default view of the map bounds using either center or bounds or fitBounds to a list of Lng,Lat coordinates. So, basically, how to plug in lng,lat coordinates and have the map default to centering these coordinates inside of the container?
Here's a Component I created, called Map in vue to output the mapbox using the component vue-mapbox listed above:
<template>
<b-row id="map" class="d-flex justify-content-center align-items-center my-2">
<b-col cols="24" id="map-holder" v-bind:class="getMapType">
<mgl-map
id="map-obj"
:accessToken="accessToken"
:mapStyle.sync="mapStyle"
:zoom="zoom"
:center="center"
container="map-holder"
:interactive="interactive"
#load="loadMap"
ref="mapbox" />
</b-col>
</b-row>
</template>
<script>
import { MglMap } from 'vue-mapbox'
export default {
components: {
MglMap
},
data () {
return {
accessToken: 'pk.eyJ1Ijoic29sb2dob3N0IiwiYSI6ImNqb2htbmpwNjA0aG8zcWxjc3IzOGI1ejcifQ.nGL4NwbJYffJpjOiBL-Zpg',
mapStyle: 'mapbox://styles/mapbox/streets-v9', // options: basic-v9, streets-v9, bright-v9, light-v9, dark-v9, satellite-v9
zoom: 9,
map: {}, // Holds the Map...
fitBounds: [[-79, 43], [-73, 45]]
}
},
props: {
interactive: {
default: true
},
resizeMap: {
default: false
},
mapType: {
default: ''
},
center: {
type: Array,
default: function () { return [4.899, 52.372] }
}
},
computed: {
getMapType () {
let classes = 'inner-map'
if (this.mapType !== '') {
classes += ' map-' + this.mapType
}
return classes
}
},
watch: {
resizeMap (val) {
if (val) {
this.$nextTick(() => this.$refs.mapbox.resize())
}
},
fitBounds (val) {
if (this.fitBounds.length) {
this.MoveMapCoords()
}
}
},
methods: {
loadMap () {
if (this.map === null) {
this.map = event.map // store the map object in here...
}
},
MoveMapCoords () {
this.$refs.mapbox.fitBounds(this.fitBounds)
}
}
}
</script>
<style lang="scss" scoped>
#import '../../styles/custom.scss';
#map {
#map-obj {
text-align: justify;
width: 100%;
}
#map-holder {
&.map-modal {
#map-obj {
height: 340px;
}
}
&.map-large {
#map-obj {
height: 500px;
}
}
}
.mapboxgl-map {
border: 2px solid lightgray;
}
}
</style>
So, I'm trying to use fitBounds method here to get the map to initialize centered over 2 Lng,Lat coordinates here: [[-79, 43], [-73, 45]]
How to do this exactly? Ok, I think I might have an error in my code a bit, so I think the fitBounds should look something like this instead:
fitBounds: () => {
return { bounds: [[-79, 43], [-73, 45]] }
}
In any case, having the most difficult time setting the initial location of the mapbox to be centered over 2 or more coordinates. Anyone do this successfully yet?
Ok, so I wound up creating a filter to add space to the bbox like so:
Vue.filter('addSpaceToBBoxBounds', function (value) {
if (value && value.length) {
var boxArea = []
for (var b = 0, len = value.length; b < len; b++) {
boxArea.push(b > 1 ? value[b] + 2 : value[b] - 2)
}
return boxArea
}
return value
})
This looks to be good enough for now. Than just use it like so:
let line = turf.lineString(this.markers)
mapOptions['bounds'] = this.$options.filters.addSpaceToBBoxBounds(turf.bbox(line))
return mapOptions
setting the initial location of the map to be centered over 2 or
more coordinates
You could use Turf.js to calculate the bounding box of all point features and initialize the map with this bbox using the bounds map option:
http://turfjs.org/docs#bbox
https://www.mapbox.com/mapbox-gl-js/api/#map
I created a few simple functions to calculate a bounding box which contains the most southwestern and most northeastern corners of the given [lng, lat] pairs (markers). You can then use Mapbox GL JS map.fitBounds(bounds, options?) function to zoom the map to the set of markers.
Always keep in mind:
lng (lon): longitude (London = 0, Bern = 7.45, New York = -74)
→ the lower, the more western
lat: latitude (Equator = 0, Bern = 46.95, Capetown = -33.9)
→ the lower, the more southern
getSWCoordinates(coordinatesCollection) {
const lowestLng = Math.min(
...coordinatesCollection.map((coordinates) => coordinates[0])
);
const lowestLat = Math.min(
...coordinatesCollection.map((coordinates) => coordinates[1])
);
return [lowestLng, lowestLat];
}
getNECoordinates(coordinatesCollection) {
const highestLng = Math.max(
...coordinatesCollection.map((coordinates) => coordinates[0])
);
const highestLat = Math.max(
...coordinatesCollection.map((coordinates) => coordinates[1])
);
return [highestLng, highestLat];
}
calcBoundsFromCoordinates(coordinatesCollection) {
return [
getSWCoordinates(coordinatesCollection),
getNECoordinates(coordinatesCollection),
];
}
To use the function, you can just call calcBoundsFromCoordinates and enter an array containing all your markers coordinates:
calcBoundsFromCoordinates([
[8.03287, 46.62789],
[7.53077, 46.63439],
[7.57724, 46.63914],
[7.76408, 46.55193],
[7.74324, 46.7384]
])
// returns [[7.53077, 46.55193], [8.03287, 46.7384]]
Overall it might even be easier to use Mapbox' mapboxgl.LngLatBounds() function.
As mentioned in the answer from jscastro in Scale MapBox GL map to fit set of markers you can use it like this:
const bounds = mapMarkers.reduce(function (bounds, coord) {
return bounds.extend(coord);
}, new mapboxgl.LngLatBounds(mapMarkers[0], mapMarkers[0]));
And then just call
map.fitBounds(bounds, {
padding: { top: 75, bottom: 30, left: 90, right: 90 },
});
If you don't want to use yet another library for this task, I came up with a simple way to get the bounding box, here is a simplified vue component.
Also be careful when storing your map object on a vue component, you shouldn't make it reactive as it breaks mapboxgl to do so
import mapboxgl from "mapbox-gl";
export default {
data() {
return {
points: [
{
lat: 43.775433,
lng: -0.434319
},
{
lat: 44.775433,
lng: 0.564319
},
// Etc...
]
}
},
computed: {
boundingBox() {
if (!Array.isArray(this.points) || !this.points.length) {
return undefined;
}
let w, s, e, n;
// Calculate the bounding box with a simple min, max of all latitudes and longitudes
this.points.forEach((point) => {
if (w === undefined) {
n = s = point.lat;
w = e = point.lng;
}
if (point.lat > n) {
n = point.lat;
} else if (point.lat < s) {
s = point.lat;
}
if (point.lng > e) {
e = point.lng;
} else if (point.lng < w) {
w = point.lng;
}
});
return [
[w, s],
[e, n]
]
},
},
watch: {
// Automatically fit to bounding box when it changes
boundingBox(bb) {
if (bb !== undefined) {
const cb = () => {
this.$options.map.fitBounds(bb, {padding: 20});
};
if (!this.$options.map) {
this.$once('map-loaded', cb);
} else {
cb();
}
}
},
// Watch the points to add the markers
points: {
immediate: true, // Run handler on mount (not needed if you fetch the array of points after it's mounted)
handler(points, prevPoints) {
// Remove the previous markers
if (Array.isArray(prevPoints)) {
prevPoints.forEach((point) => {
point.marker.remove();
});
}
//Add the new markers
const cb = () => {
points.forEach((point) => {
// create a HTML element for each feature
const el = document.createElement('div');
el.className = 'marker';
el.addEventListener('click', () => {
// Marker clicked
});
el.addEventListener('mouseenter', () => {
point.hover = true;
});
el.addEventListener('mouseleave', () => {
point.hover = false;
});
// make a marker for each point and add to the map
point.marker = new mapboxgl.Marker(el)
.setLngLat([point.lng, point.lat])
.addTo(this.$options.map);
});
};
if (!this.$options.map) {
this.$once('map-loaded', cb);
} else {
cb();
}
}
}
},
map: null, // This is important to store the map without reactivity
methods: {
mapLoaded(map) {
this.$options.map = map;
this.$emit('map-loaded');
},
},
}
It should work fine as long as your points aren't in the middle of the pacific juggling between 180° and -180° of longitude, if they are, simply adding a check to invert east and west in the return of the bounding box should do the trick

i can't access data values from methods in my vue.js component?

I can’t access the values lat , lng from data() in maps() method.
my vue.js component
code link : https://gist.github.com/melvin2016/c8082e27b9c50964dcc742ecff853080
console image of lat,lng
enter image description here
<script>
import Vue from 'vue';
import navbarSec from './navbarSec.vue';
export default {
data(){
return{
lat: '',
lng: '',
mapState: window.mapState,
from:'',
to:'',
placesFrom:[],
placesTo:[]
};
},
components:{
'navbar':navbarSec
},
created(){
var token = this.$auth.getToken();
this.$http.post('http://localhost:3000/book',{},{headers: {'auth':token}}).then(function(data){
this.session = true;
})
.catch(function(data){
this.session = false;
this.$auth.destroyToken();
Materialize.toast(data.body.message, 6000,'rounded');
this.$router.push('/login');
});
if(navigator.geolocation){
navigator.geolocation.getCurrentPosition((data)=>{
this.lat = data.coords.latitude;
this.lng = data.coords.longitude;
this.from=data.coords.latitude+' , '+data.coords.longitude;
});
}else{
Materialize.toast("Cannot Get Your Current Location !", 6000,'rounded');
}
},
mounted(){
if (this.mapState.initMap) {// map is already ready
var val = this.mapState.initMap;
console.log(val);
this.maps();
}
},
watch: {
// we watch the state for changes in case the map was not ready when this
// component is first rendered
// the watch will trigger when `initMap` will turn from `false` to `true`
'mapState.initMap'(value){
if(value){
this.maps();
}
},
from : function(val){
if(val){
var autoComplete = new google.maps.places.AutocompleteService();
autoComplete.getPlacePredictions({input:this.from},data=>{
this.placesFrom=data;
});
}
},
to:function(val){
if(val){
var autoComplete = new google.maps.places.AutocompleteService();
autoComplete.getPlacePredictions({input:this.to},data=>{
this.placesTo=data;
});
}
}
},
methods:{
maps(){
var vm = this;
var lati = vm.lat;
var lngi = vm.lng;
console.log(lati+' '+lngi);
var map;
var latlng = {lat: lati, lng:lngi };
console.log(latlng);
this.$nextTick(function(){
console.log('tickkkk');
map = new google.maps.Map(document.getElementById('maplo'), {
zoom: 15,
center: latlng
});
var marker = new google.maps.Marker({
position: latlng,
map: map
});
});
}
}
}
</script>
This is happening because you're calling maps() in the mounted at which point, the navigator.geolocation.getCurrentPosition((data) => {}) code hasn't resolved. With that in mind, call this.maps() within the getCurrentPosition method i.e:
navigator.geolocation.getCurrentPosition((data)=>{
this.lat = data.coords.latitude;
this.lng = data.coords.longitude;
this.from=data.coords.latitude+' , '+data.coords.longitude;
this.maps()
});
I've not looked in detail but you might be able to change the bits within the maps() method to remove the nextTick stuff when you do this as you'll be calling it a lot later in the cycle at which point everything will have been rendered.

Call GoogleMap MarkerClusterer method from typescript-based angular controller

I've started to investigate TypeScript approach in my project and currently bit confused how to correctly organize the call to MarkerClusterer method. I currently have to type-definitions references:
///<reference path="../../typings/angularjs/angular.d.ts" />
///<reference path="../../typings/google.maps.d.ts" />
But for MarkerClusterer js I was unable to find definition ts library. My code now looks so:
class paspController {
public map: any;
public markers;
public mapTab: boolean;
public currentId: number;
//Some code
showTab(tabIndex: number) {
if (tabIndex == 2) {
this.mapTab = true;
var that = this;
setTimeout(function () {
this.options = {
zoom: 2,
center: new google.maps.LatLng(1, 1),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
if (!that.map) {
that.map = new google.maps.Map(document.getElementById('map'), this.options);
}
jQuery.ajax({
type: "GET",
url: 'GetDivesWithCoordinates/' + that.currentId,
success: function (data) {
that.markers = [];
var marker;
for (var i = 0; i < data.length; i++) {
marker = new google.maps.Marker({ map: that.map, draggable: false, title: data[i].Location + ": " + data[i].DiveComment, position: new google.maps.LatLng(data[i].CoordinateX, data[i].CoordinateY) });
that.markers.push(marker);
}
// THIS IS MY PROBLEM => var markerCluster = new MarkerClusterer(that.map, markers);
},
error: function (e) {
},
async: false
});
}, 100);
}
}
How should I correctly call the MarkerClusterer, or maybe I should put it outside the controller logic?
THIS IS MY PROBLEM => var markerCluster = new MarkerClusterer(that.map, markers);
Declare it :
declare var MarkerClusterer:any;
And typescript will not complain anymore.
More : http://basarat.gitbooks.io/typescript/content/docs/types/migrating.html
Use the below npm package instead of adding scripts directly in angular.
Add this package to your node_modules
npm i #googlemaps/markerclustererplus
In your Ts file import this:
import MarkerClusterer from '#googlemaps/markerclustererplus';
const markerCluster = new MarkerClusterer(map, markers);
Reference: https://github.com/googlemaps/js-markerclustererplus
I put it after the:
import { Component, OnInit, ViewChild, ElementRef } from '#angular/core';
declare var MarkerClusterer: any;
and before
#Component({

Categories