grey box google maps and angular 2 - google-maps

I have a problem with angular 2 and the API v3 of google maps, the problem is that when I load the page through the router outlet, the map is a grey box, but when I refresh the page the map load correctly, I'm using the js library import on the index page, and the map is loaded in a component.
this is the view of the map
I tried with trigger rezise but don't work. I think that is a problem with the library load or similar.
this is the code:
import {Component, OnInit} from "angular2/core";
import {MapsService} from "../maps/maps.service";
import {mapsIconService} from "./maps.icon.service";
import {BrowserDomAdapter} from 'angular2/platform/browser';
#Component({
selector: "div-map",
template: `
<div id="map" style="height: 500px" class="maps"> </div> `,
providers: [MapsService, mapsIconService, BrowserDomAdapter],
style: `
.maps{
overflow:visible;
}
`
})
export class Maps {
map;
snappedCoordinates = [];
points:string = "";
map:Map;
drawingManager;
placeIdArray = [];
polylines = [];
markers = [];
placeIds = [];
infoWindows = [];
snappedPolyline;
showMap = false;
lineSymbol = {
path: google.maps.SymbolPath.CIRCLE,
scale: 8,
strokeColor: '#005db5',
strokeWidth: '#005db5'
};
mapOptions = {
zoom: 15,
center: {lat: 37.38658313258027, lng: -122.05207727132837},
};
constructor(private _dom:BrowserDomAdapter, private _mapService:MapsService, private _mapIconService:mapsIconService) {
// google.maps.visualRefresh = true;
}
drawSnappedPolyline(snappedCoordinates) {
this.snappedPolyline = new google.maps.Polyline({
path: snappedCoordinates,
strokeColor: 'black',
strokeWeight: 3
});
this.polylines.push(this.snappedPolyline);
}
animateCircle(polyline) {
var count = 0;
// fallback icon if the poly has no icon to animate
var defaultIcon = [
{
icon: this.lineSymbol,
offset: '100%'
}
];
window.setInterval(function () {
count = (count + 1) % 300;
var icons = defaultIcon;
icons[0].offset = (count / 3) + '%';
polyline.set('icons', icons);
}, 300);
}
setMarker(lat, lng, id) {
var marker = new google.maps.Marker({
position: this.map.getCenter()/*new google.maps.LatLng(lat, lng)*/,
icon: {url: 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(this._mapIconService.getIcon(id))},
draggable: false,
map: this.map
});
}
SetAllMarkers(points) {
for (var i in points) {
this.setMarker(points[i].lat, points[i].lng, points[i].id);
}
}
ngOnInit() {
this.map = new google.maps.Map(this._dom.query("#map"), this.mapOptions);
google.maps.event.trigger(this.map, 'resize');
this._mapService.goData().subscribe(data=> {
this.drawSnappedPolyline(this._mapService.processSnapToRoadResponse(data));
this.setMarker(37.38658313258027, -122.05207727132837, 0);
this.snappedPolyline.setMap(this.map);
this.animateCircle(this.snappedPolyline);
});
}
}
any one have a idea about this? thank in advance

the problem was semantic UI, because he insert the code into a "pusher" and this cause a problem with the all elements

Related

google map error - ReferenceError: google is not defined in ionic 3 app

I am loading google map into my ionic 3 app page. When I load the application using the browser the page is loading fine but when i make the application apk (using ionic cordova build android --prod) the map is not loading and throwing an exception if ReferenceError: google is not defined. I have been googling for few days and I have applied all the solution I got but no use at all. Can anyone please help me to overcome this issue.
My map.ts code is as follows:
import {Component, ViewChild, ElementRef} from '#angular/core';
import {IonicPage, NavController, NavParams, PopoverController, LoadingController, MenuController} from 'ionic-angular';
import {Keyboard} from '#ionic-native/keyboard';
import {Geolocation, Geoposition} from '#ionic-native/geolocation';
import {NativeGeocoder, NativeGeocoderReverseResult} from '#ionic-native/native-geocoder';
import {LocationAccuracy} from '#ionic-native/location-accuracy';
declare var google: any;
#IonicPage()
#Component({
selector: 'page-map',
templateUrl: 'map.html',
})
export class Map {
latLng: any;
#ViewChild('map') mapElement: ElementRef;
map: any;
showFooter: boolean = true;
constructor(public navCtrl: NavController,
public navParams: NavParams,
public popoverCtrl: PopoverController,
private geolocation: Geolocation,
public locac: LocationAccuracy,
public loadingCtrl: LoadingController,
public keyboard: Keyboard,
private menu: MenuController,
public geocoder: NativeGeocoder,) {
}
ionViewDidLoad() {
this.getLocation();
this.menu.swipeEnable(false);
}
getLocation() {
this.geolocation.getCurrentPosition().then((resp) => {
let map = new google.maps.Map(document.getElementById('map'));
var uluru = {lat: -25.363, lng: 131.044};
this.latLng = new google.maps.LatLng(resp.coords.latitude, resp.coords.longitude);
let mapOptions = {
center: this.latLng,
zoom: 18,
mapTypeId: google.maps.MapTypeId.ROADMAP,
enableHighAccuracy: true
};
this.map = new google.maps.Map(this.mapElement.nativeElement, mapOptions);
let marker = new google.maps.Marker({
map: this.map,
animation: google.maps.Animation.DROP,
position: this.latLng,
center: this.latLng,
icon: {
url: 'assets/img/pin.png',
size: new google.maps.Size(25, 48)
},
optimized: false,
});
// geocode reverse
var geocoder = geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(resp.coords.latitude, resp.coords.longitude);
geocoder.geocode({'latLng': latlng}, function (results, status) {
console.log(results);
alert('Status : ' + status);
this.currentLocation = this.value = "My value";
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
document.getElementById("currentlocation").setAttribute('value', results[1].formatted_address);
}
}
});
// geocode reverse end
// Route and direction
var source, destination;
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
directionsDisplay = new google.maps.DirectionsRenderer({'draggable': true});
// current location input
let currentlocationinput = document.getElementById('currentlocation');
let currentlocationsearchBox = new google.maps.places.SearchBox(currentlocationinput);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(currentlocationinput);
// destination location input
let destinationinput = document.getElementById('destination');
let destinationsearchBox = new google.maps.places.SearchBox(destinationinput);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(destinationinput);
// Direction
var directionsService = new google.maps.DirectionsService;
var directionsDisplay = new google.maps.DirectionsRenderer;
directionsDisplay.setMap(map);
// on drag and dragend header style change
this.map.addListener('dragstart', function (event) {
document.querySelector(".header")['style'].transform = 'translate3d(0px, -320px, 0px)';
document.querySelector(".scroll-content").classList.add("no_margin");
document.querySelector(".footer")['style'].transform = 'translate3d(0px, 320px, 0px)';
});
this.map.addListener('dragend', function (event) {
document.querySelector(".header")['style'].transform = 'translate3d(0px, 0px, 0px)';
document.querySelector(".scroll-content").classList.remove("no_margin");
document.querySelector(".footer")['style'].transform = 'translate3d(0px, 0px, 0px)';
});
// on drag and dragend header style change end
}).catch((error) => {
alert(error);
console.log('Error getting location', error);
})
}
}
i am hanging on this for few days. if any one could solve, please help me out. Thanks in advance.
Check that,
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=API_KEY&callback=initMap">
</script>
you can add it to index.js or not
i think maps is not loaded when you access it.
[SOLVED]
Almost about to give up until i came across his answer.
Mark Veenstra - Solution is here
Could be useful to someone who is hanging with the same issue as i was hanging.
Cheers..!!

Trying to get the marker var out of the foreach loop for markerCluster to work, what is the easiest way of doing this?

I am trying to add MarkerClusters to my map, however my marker variable is within a function with a foreach loop used to retrieve Instagram API data, what is the best possible way to get MarkerClusters working?
I tried wrapping the initMap function around the setMarkers function, putting the markerCluster variable within the setMarkers function and within the foreach loop but it just keeps showing the markers (pictures in my case)
<script>
let coords = document.getElementById("places").innerHTML;
let parts = coords.split(",");
let finalResult = []
while (parts.length) {
let newArr = parts.splice(0, 3);
finalResult.push(newArr);
}
console.log(finalResult)
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: {
lat: 52.9,
lng: 101.2
}
});
setMarkers(map);
}
function setMarkers(map) {
finalResult.forEach((place) => {
var image = {
url: place[0],
scaledSize: new google.maps.Size(64, 64),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(32, 32)
};
var shape = {
coords: [1, 1, 1, 20, 18, 20, 18, 1],
type: 'poly'
};
var myLatlng = new google.maps.LatLng(place[1], place[2]);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
icon: image,
shape: shape
});
})
var markerCluster = new MarkerClusterer(map, marker,
{imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'});
}
</script>
<script src="https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/markerclusterer.js">
</script>
One option is to create the MarkerClusterer inside your setMarkers function, then add the markers to it individually as you create them with the .addMarker method.
function setMarkers(map) {
var markerCluster = new MarkerClusterer(map, [], {
imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'
});
finalResult.forEach((place) => {
var image = {
url: place[0],
};
var myLatlng = new google.maps.LatLng(place[1], place[2]);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
icon: image,
});
markerCluster.addMarker(marker);
});
proof of concept fiddle
code snippet:
let coords = document.getElementById("places").innerHTML;
let parts = coords.split(",");
let finalResult = []
while (parts.length) {
let newArr = parts.splice(0, 3);
finalResult.push(newArr);
}
console.log(finalResult)
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 3,
center: {
lat: -38,
lng: 150
}
});
setMarkers(map);
}
function setMarkers(map) {
var bounds = new google.maps.LatLngBounds();
var markerCluster = new MarkerClusterer(map, [], {
imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'
});
finalResult.forEach((place) => {
var image = {
url: place[0],
};
var myLatlng = new google.maps.LatLng(place[1], place[2]);
bounds.extend(myLatlng);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
icon: image,
});
markerCluster.addMarker(marker);
map.fitBounds(bounds);
});
}
html,
body,
#map {
height: 100%;
margin: 0;
padding: 0;
}
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap"></script>
<script src="https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/markerclusterer.js"></script>
<div id="places" style="display:none">https://maps.google.com/mapfiles/ms/micons/blue.png,-31.563910,147.154312, https://maps.google.com/mapfiles/ms/micons/blue.png,-33.718234,150.363181, https://maps.google.com/mapfiles/ms/micons/blue.png,-33.727111,150.371124, https://maps.google.com/mapfiles/ms/micons/blue.png,-33.848588,151.209834,https://maps.google.com/mapfiles/ms/micons/blue.png,-33.851702,151.216968,
https://maps.google.com/mapfiles/ms/micons/blue.png,-34.671264,150.863657, https://maps.google.com/mapfiles/ms/micons/blue.png,-35.304724,148.662905, https://maps.google.com/mapfiles/ms/micons/blue.png,-36.817685,175.699196,https://maps.google.com/mapfiles/ms/micons/blue.png,-36.828611,175.790222,
https://maps.google.com/mapfiles/ms/micons/blue.png,-37.750000,145.116667, https://maps.google.com/mapfiles/ms/micons/blue.png,-37.759859,145.128708, https://maps.google.com/mapfiles/ms/micons/blue.png,-37.765015,145.133858,https://maps.google.com/mapfiles/ms/micons/blue.png,-37.770104,145.143299,
https://maps.google.com/mapfiles/ms/micons/blue.png,-37.773700,145.145187, https://maps.google.com/mapfiles/ms/micons/blue.png,-37.774785,145.137978, https://maps.google.com/mapfiles/ms/micons/blue.png,-37.819616,144.968119, https://maps.google.com/mapfiles/ms/micons/blue.png,-38.330766,144.695692,
https://maps.google.com/mapfiles/ms/micons/blue.png,-39.927193,175.053218, https://maps.google.com/mapfiles/ms/micons/blue.png,-41.330162,174.865694, https://maps.google.com/mapfiles/ms/micons/blue.png,-42.734358,147.439506, https://maps.google.com/mapfiles/ms/micons/blue.png,-42.734358,147.501315,
https://maps.google.com/mapfiles/ms/micons/blue.png,-42.735258,147.438000, https://maps.google.com/mapfiles/ms/micons/blue.png,-43.999792,170.463352,
</div>

Use Google Places Library to show all location markers for a predetermined keyword with Google Maps and Ionic

I want to display a marker for each Place search result on my map but it doesn't work.
---EDIT---
I have tried to debug figure out what I am missing and why the markers are not showing up, but I am not able to figure it out. Even if the answer is very obvious, I might not be able to see it with what I currently have. I had edited the code a little bit with the setMarker() function and the options of the marker to be displayed on the map created, but that does not seem to be the answer to why the markers wont show up. I shouldn't have to create markers at specific Latitudes and Longitudes but instead search the area around the current location using a predetermined search keyword which in this case would be "McDonalds" (this search keyword is being used for testing).
map.html:
<ion-header>
<ion-navbar>
<ion-title>
Map
</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<div id='map'>
</div>
<ion-fab bottom right id="locate">
<button ion-fab
(click)="locationClick()" color="white"><ion-icon ios="ios-locate-outline" md ="md-locate" color="primary"></ion-icon></button>
</ion-fab>
<ion-fab top left id="compass-fab">
<button ion-fab mini (click)="compassClick()" color="white" id="compass"></button>
</ion-fab>
<ion-fab top right id="layers">
<button ion-fab mini id="layers-button" color="white"><ion-icon name="SMAPP-layers"></ion-icon></button>
<ion-fab-list side="bottom">
<button ion-fab mini (click)="trafficClick()" id="traffic" color="white"></button>
<button ion-fab mini (click)="transitClick()" id="transit" color="white"></button>
<button ion-fab mini (click)="bicycleClick()" id="bicycle" color="white"></button>
</ion-fab-list>
</ion-fab>
</ion-content>
map.ts:
declare var google: any;
#Component({
selector: 'page-map',
templateUrl: 'map.html',
})
export class OfficeLocatorPage {
#ViewChild(Navbar) navBar: Navbar;
#ViewChild('map') mapElement: ElementRef;
map: any;
mapOptions:any;
infowindow: any;
trafficEnabled = false;
transitEnabled = false;
bicycleEnabled = false;
markers = [];
trafficLayer = new google.maps.TrafficLayer();
transitLayer = new google.maps.TransitLayer();
bicycleLayer = new google.maps.BicyclingLayer();
constructor(private navCtrl: NavController, private platform: Platform,
private geolocation: Geolocation) {}
ionViewDidLoad() {
this.navBar.backButtonClick = (e:UIEvent)=>{
this.navCtrl.pop({animate: true, animation: "transition", direction: "left", duration: 300});
};
}
ionViewDidEnter() {
this.platform.ready().then(() => {
this.loadMap();
});
}
locationClick() {
this.geolocation.getCurrentPosition({ maximumAge: 3000, timeout: 5000, enableHighAccuracy: true }).then((resp) => {
let myLocation = new google.maps.LatLng(resp.coords.latitude,resp.coords.longitude);
this.map.setCenter(myLocation);
});
}
compassClick() {
this.map.animateCamera({
target: this.map.getCameraTarget(),
tilt: 0,
bearing: 0,
duration: 1000
});
}
trafficClick() {
if (this.transitEnabled == true) {
this.transitClick();
this.trafficEnabled = true;
this.trafficLayer.setMap(this.map);
} else if (this.trafficEnabled == false) {
this.trafficEnabled = true;
this.trafficLayer.setMap(this.map);
} else {
this.trafficEnabled = false;
this.trafficLayer.setMap(null);
}
}
transitClick() {
if (this.trafficEnabled == true) {
this.trafficClick();
this.transitEnabled = true;
this.transitLayer.setMap(this.map);
} else if (this.transitEnabled == false) {
this.transitEnabled = true;
this.transitLayer.setMap(this.map);
} else {
this.transitEnabled = false;
this.transitLayer.setMap(null);
}
}
bicycleClick() {
this.bicycleEnabled = !this.bicycleEnabled;
if (this.bicycleEnabled) {
this.bicycleLayer.setMap(this.map);
} else {
this.bicycleLayer.setMap(null);
}
}
loadMap() {
this.geolocation.getCurrentPosition({ maximumAge: 3000, timeout: 5000, enableHighAccuracy: true }).then((resp) => {
let myLocation = new google.maps.LatLng(resp.coords.latitude,resp.coords.longitude);
this.map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: myLocation,
disableDefaultUI: true
});
});
let watch = this.geolocation.watchPosition();
watch.subscribe((data) => {
this.deleteMarkers();
let updatelocation = new google.maps.LatLng(data.coords.latitude,data.coords.longitude);
let image = {
url: "assets/icon/blue_dot.png", // url
scaledSize: new google.maps.Size(25, 33), // scaled size
origin: new google.maps.Point(0,0), // origin
anchor: new google.maps.Point(0, 0) // ancho
};
this.addMarker(updatelocation, image);
this.setMapOnAll(this.map);
});
var request = {
query: 'McDonalds',
fields: ['photos', 'formatted_address', 'name', 'rating', 'opening_hours', 'geometry'],
};
let service = new google.maps.places.PlacesService(this.map);
service.findPlaceFromQuery(request, callback);
function callback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (let i = 0; i < results.length; i++) {
let placeLoc = results[i].geometry.location;
this.addMarker(placeLoc, 'red');
}
}
this.setMapOnAll(this.map);
}
}
addMarker(location, image) {
let marker = new google.maps.Marker({
position: location,
map: this.map,
icon: image
});
this.markers.push(marker);
}
setMapOnAll(map) {
for (var i = 0; i < this.markers.length; i++) {
this.markers[i].setMap(map);
}
}
clearMarkers() {
this.setMapOnAll(null);
}
deleteMarkers() {
this.clearMarkers();
this.markers = [];
}
}
I would recommend you to you use setMap(map);. There is a good example that you will utilize from. I used it couple month before and works perfect. Hope it helps.
I have figured out that the places library was not being accessed correctly but is now, I have also updated the code to show what needs to be done to gather information using the places function, findPlaceByQuery(). The Google JavaScript API Documentation is not accurate in how to display search results based on a query. Here is the updated code on how to do it, once you have the Places Library set up correctly in the script tag to be used (I have also included the code on how to correctly display the markers, scopeObj is the class object passed into the loadMap() function):
map.ts:
var request ={
locationBias: this.myLocation,
query: "McDonalds",
fields: ['photos', 'formatted_address', 'name', 'rating', 'opening_hours', 'geometry']
};
var callbackCount = 0;
function callback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (let i = 0; i < results.length; i++) {
let placeLoc = results[i].geometry.location;
scopeObj.addMarker(placeLoc, 'red');
}
}
callbackCount++;
};
let service = new google.maps.places.PlacesService(this.map);
service.findPlaceFromQuery(request, callback);
continueExec();
function continueExec() {
if (callbackCount < 1) {
setTimeout(continueExec, 1000);
return;
}
scopeObj.setMapOnAll(this.map);
}
}
addMarker(location, image) {
let marker = new google.maps.Marker({
position: location,
map: this.map,
icon: image
});
this.markers.push(marker);
}
setMapOnAll(map) {
for (var i = 0; i < this.markers.length; i++) {
var marker = new google.maps.Marker({
position: this.markers[i].getPosition(),
map: this.map,
title: 'Hello World!'
});
}
}
Places API script to be added into index.html above all other script tags in the tag:
<script src="https://maps.googleapis.com/maps/api/js?v=3&key=....&libraries=places" type="text/javascript"></script>

Google places autocomplete inside a react component

I am trying to build a google map component and everything is working fine with the Google Maps API v3 but not the Autocomplete functionality.
This is the code I am using:
The Google Map component
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
const Marker = React.createClass({
componentDidMount: function() {
console.log("Marker on mount");
},
render: function() {
return false;
}
});
export default Marker;
const GoogleMap = React.createClass({
componentDidMount: function() {
var mapOptions = {
center: this.createLatLng(this.props.center),
zoom: this.props.zoom || 14
};
var map = new google.maps.Map(ReactDOM.findDOMNode(this), mapOptions);
//Render all the markers (children of this component)
React.Children.map(this.props.children, (child) => {
var markerOptions = {
position: this.createLatLng(child.props.position),
title: child.props.title || "",
animation: google.maps.Animation.DROP,
icon: child.props.icon || null,
map: map,
autocomplete:new google.maps.places.AutocompleteService()
};
var marker = new google.maps.Marker(markerOptions);
if(child.props.info) {
var infowindow = new google.maps.InfoWindow({
content: child.props.info
});
marker.addListener('click', function() {
infowindow.open(map, marker);
});
}
});
var input = this.refs.search;
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
var autocomplete = new google.maps.places.Autocomplete(input);
autocomplete.bindTo('bounds', map);
this.setState({map});
},
createLatLng: function(element) {
return new google.maps.LatLng(element.lat, element.lng);
},
render: function() {
return (
<div className="map">
<input ref="search"/>
</div>
)
}
});
export default GoogleMap;
And this is where I call the component
import React, {Component} from 'react';
import GoogleMap from './GoogleMap';
import Marker from './GoogleMap';
import Geosuggest from 'react-geosuggest';
class DoodlesMap extends Component {
state = {
center: null,
marker: null,
directions: null
};
componentWillMount() {
navigator.geolocation.getCurrentPosition((position) => {
this.setState({
center: {
lat: position.coords.latitude,
lng: position.coords.longitude
},
marker: {
position: {
lat: position.coords.latitude,
lng: position.coords.longitude
}
}
});
});
}
renderYouAreHereMarker() {
return (
<Marker
position={this.state.center}
icon="../../img/you-are-here.png"
/>
)
}
render() {
if (!this.state.center) {
return (
<div>Loading...</div>
)
}
return (
<div>
<GoogleMap
center={this.state.center}
zoom={15}
>
{this.renderYouAreHereMarker()}
<Marker
position={{lat: 41.317334, lng: -72.922989}}
icon="../../img/marker.png"
info="Hola"
/>
<Marker
position={{lat: 41.309848, lng: -72.938234}}
icon="../../img/marker.png"
info="Epi"
/>
</GoogleMap>
</div>
);
}
}
export default DoodlesMap;
I do not receive any console error. The map is displayed correctly (with the markers as children) the input also, but does not make the autocomplete.
Thank you in advance!!
I figure it out, and was very simple issue.
The thing was that I did not "enable" the places API in my google developer console.
Once I did this everything worked fine!!
It took me quite some time to get the google-places-autocomplete feature working nicely with a React Component. I did however manage to figure it out and wrote a short tutorial on it over here.
Medium Tutorial Post!
TL;DR of tutorial: You have to use a library called react-scripts to render the google-maps-places library after the component has mounted. Most of the time the reason that the autocomplete doesn't work is because the library did not load properly.

AngularJs- TypeError: Cannot read property 'latitude' of undefined

I want to show Google map with draggable marker in my page . Here is my code:
header.php :
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3&sensor=true"></script>
map.js:
app.directive('mapDirective',function(){
return {
templateUrl: 'map.html',
restrict: 'EA',
require: '?ngModel',
scope:{
myModel: '=ngModel'
},
link: function(scope , element, attrs , ngModel){
var mapOptions;
var googleMap;
var searchMarker;
var searchLatLng;
scope.searchLocation = {
latitude: 48.137273,
longitude: 11.575251
};
ngModel.$render = function(){
console.log("hhh");
searchLatLng = new google.maps.LatLng(scope.myModel.latitude, scope.myModel.longitude);
mapOptions = {
center: searchLatLng,
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
googleMap = new google.maps.Map(element[0],mapOptions);
searchMarker = new google.maps.Marker({
position: searchLatLng,
map: googleMap,
draggable: true
});
google.maps.event.addListener(searchMarker, 'dragend', function(){
scope.$apply(function(){
scope.myModel.latitude = searchMarker.getPosition().lat();
scope.myModel.longitude = searchMarker.getPosition().lng();
});
}.bind(this));
};
scope.$watch('myModel', function(value){
var myPosition = new google.maps.LatLng(scope.myModel.latitude, scope.myModel.longitude);
searchMarker.setPosition(myPosition);
}, true);
}
}
});
map.html:
<div>
<div style="display: block; height: 200px; width: 100%; ">
</div>
</div>
index.html:
<map-directive ng-model="testModel"></map-directive>
Actually , I got this error :
TypeError: Cannot read property 'latitude' of undefined
How to solve it?
EDITED:
I change my maps.js:
app.directive('mapDirective',function(){
return {
templateUrl: '/app/user/ngApp/templates/libsView/templates/directives/map.html',
restrict: 'EA',
require: '?ngModel',
scope:{
myModel: '=ngModel'
},
controller: function ($scope) {
$scope.searchLocation = {
latitude: 48.137273,
longitude: 11.575251
};
},
link: function(scope , element, attrs , ngModel){
var mapOptions;
var googleMap;
var searchMarker;
var searchLatLng;
ngModel.$render = function(){
console.log("hhh");
searchLatLng = new google.maps.LatLng(scope.myModel.latitude, scope.myModel.longitude);
mapOptions = {
center: searchLatLng,
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
googleMap = new google.maps.Map(element[0],mapOptions);
searchMarker = new google.maps.Marker({
position: searchLatLng,
map: googleMap,
draggable: true
});
google.maps.event.addListener(searchMarker, 'dragend', function(){
scope.$apply(function(){
scope.myModel.latitude = searchMarker.getPosition().lat();
scope.myModel.longitude = searchMarker.getPosition().lng();
});
}.bind(this));
};
scope.$watch('myModel', function(value){
var myPosition = new google.maps.LatLng(scope.myModel.latitude, scope.myModel.longitude);
searchMarker.setPosition(myPosition);
}, true);
}
}
});
But it doesn't change.
myModel variable should contains latitude and longitude values. which should be set from
<map-directive ng-model="testModel"></map-directive>
You need to create a object as below in your controller and assign this object to directive as above html.
var testModel = {
latitude:1.2323,
longitude:2.3434
};