0

I am trying to create a website that has a google map in one column and in the second is a list of items with location elements. On clicking one of these items, I would like to drop a pin in the google map. I am having trouble updating the markers on the google map. I can add one marker at initialization of the map, but cannot get new markers to be dropped. Here is my code: https://gist.github.com/aarongirard/32f80f17e19d3e0389da. The issue occurs in the if else clause within the click function.

Any help is appreciated!!

//global variables //google map var map; var marker; var currentMakerli; function initialize() { //set latlng of starting window of map var mapOptions = { center: { lat: 34.073609, lng: -118.562313}, zoom: 14, }; //set map using above options and attach to given element map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions); //construct new marker; constructor takes an object with position and title properties //get lat long for first marker var latlng = new google.maps.LatLng(34.073514, -118.562348); marker = new google.maps.Marker({ position: latlng, map: map, title: "Home" }); //on click of li add new marker or remove if marker already exists $(".DataList li").click(function(){ //if current marker set to this already //remove marker if ( $(this).attr('id') === 'current') { marker.setMap(null); $(this).attr('id', ''); } else { $(this).attr('id','current'); var latlngarr = getLatLngFromString($(this).attr('data-position')); var lat = latlngarr[0]; var lng = latlngarr[1]; thisLatlng = new google.maps.LatLng(lat,lng); var marker = new google.maps.Marker({ position: latlng, map: map, }); //marker.setMap(map); } }); } //set map google.maps.event.addDomListener(window, 'load', initialize); function getLatLngFromString(string){ var array = string.split(','); array[0] = parseFloat(array[0]); array[1] = parseFloat(array[1]); return array; } 
4
  • why did you comment //marker.setMap(map) and do you get what you expect from getLatLngFromString() Commented Jul 18, 2015 at 0:09
  • Sorry i should have mentioned. The <li> items have a attr data-position which holds a string "lat, lng". This method parses this string so that I can use it as input for the marker constructor. I commented it out because it wasn't working and tried using the map:map property in the marker constructor instead Commented Jul 18, 2015 at 0:25
  • Try setting map: null and then marker.setMap(map), double check that marker and map are actually the objects you want to use. just guesses though, I dont see any obvious problem Commented Jul 18, 2015 at 0:40
  • 1
    Post your code in the question...we shouldn't have to go to another site to see it. Also that link may change rendering the question useless in the future for others with similar problem Commented Jul 18, 2015 at 0:48

1 Answer 1

1

You must store the marker in a way in which you are able to get a relation between the <li> and the marker, e.g. via $.data

simple example:

function initialize() { //set latlng of starting window of map var map = new google.maps.Map($('#map-canvas')[0], { center: { lat: 34.073609, lng: -118.562313}, zoom: 14, disableDefaultUI:true }), home = new google.maps.Marker({ position: { lat: 34.073514, lng: -118.562348}, map: map, title: "Home", icon:'http://maps.google.com/mapfiles/arrow.png' }); map.controls[google.maps.ControlPosition.TOP_LEFT].push($(".DataList")[0]); //on click of li add new marker or remove if marker already exists $(".DataList li").click(function(){ var that=$(this); //when there is no marker associated with the li we create a new if(!that.data('marker')){ that.data('marker',new google.maps.Marker({position:(function(ll){ return new google.maps.LatLng(ll[0],ll[1]); }(that.data('position').split(/,/)))})); } var marker=that.data('marker'); //simply check the markers map-property to decide //if the marker has to be added or removed if(marker.getMap()){ that.removeClass('current'); marker.setMap(null); } else{ that.addClass('current'); marker.setMap(map); } }); } google.maps.event.addDomListener(window, 'load', initialize);
 html,body,#map-canvas{height:100%;margin:0;padding:0} .current{background:#f1f1f1;} .DataList{background:#fff;padding:0;} .DataList li{cursor:pointer;padding:4px;list-style-position:inside;}
<script src="https://code.jquery.com/jquery-latest.js"></script> <script src="https://maps.googleapis.com/maps/api/js?v=3"></script> <ul class="DataList"> <li data-position="34.0717825, -118.567396">Santa Ynez Canyon Park</li> <li data-position="34.0787989, -118.572502">Palisades Country Estates</li> <li data-position="34.078375, -118.56098">Highland Recreation Center</li> </ul> <div id="map-canvas"></div>


Related to the comments:

You didn't mess up with variable-names, my examples uses less variables, but you may use more variables when you want to.

I prefer to avoid variables when I need to access an object only once.


The marker will be created here(and stored as a property of the <li/>):

//when there is no marker associated with the li we create a new if(!that.data('marker')){ that.data('marker',new google.maps.Marker({position:(function(ll){ return new google.maps.LatLng(ll[0],ll[1]); }(that.data('position').split(/,/)))})); } 

The part that splits the data-position-attribute is this:

(function(ll){ return new google.maps.LatLng(ll[0],ll[1]); }(that.data('position').split(/,/))) 

It's a so-called "self-executing anonymous function", which returns the desired value(a LatLng) which will be used as position of the Marker. The splitted data-position-attribute will be used as argument for this function

that.data('position').split(/,/) 

getMap() returns whatever the map-property has been set to, either a google.maps.Map-instance or null (when you want to remove the marker or when the property is not set). Although it's not a boolean value it evaluates to either true(when it's a map) or false(when it's null), so it may be used as condition.


The that-variable is always a new variable, that's correct, but it will always be a reference to the same object, the clicked <li/>. The marker has been stored as property of this object.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks! This answer helps a lot. I looked at my code and figured out I actually was messing up variable references I believe. I do have a few question if you would indulge me as a JS newby 1. in the code section where you split the 'position' item with .split. Is this passed as an arg to the function above it? I'm unfamiliar with this syntax. 2. In the second if statement you call .getMap as if it returns a boolean but I checked the documentaiton and it returns a map object. How can this be used in this context?
One other thing: I get how it adds a marker. However, I do no get how (in the click function), it removes a marker. How does this line of code (var marker = that.data('marker');) access the marker that was created on a previous click. I thought the 'that' variable would be destroyed after the execution of a click and I don't see a reference to the marker being stored in the 'this'.
@AaronGirard: See my edited answer for the explanations
Thanks for being so in depth. I really appreciate the time you put into this. I get the code now and have definitely learned a few things. cheers, Aaron

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.