m.planchon m.planchon - 6 months ago 65
Javascript Question

Difficulties to pass a parameter in callback function (Google Map API Markers)

I have a problem with my code. Indeed, I'm trying to give a value of an array as a parameter, but in the callback fonction, the value I get is 'undefined'.

My objective is to create customized markers in function of the category of a place (catLieu) and the type of this place (typeLieu). It works for category but I have difficulties with the type.

This is my code (a part of it):

var catLieu;
var typeLieu;
var education =['school', 'university'];

function performSearch() {
clearMaps();
var i;

var clickedEducation = [];
for (i=0;i<education.length;i++)
{
var checkEducation=document.getElementById(education[i])
if (checkEducation.checked)
{
clickedEducation.push(education[i])
}
}

if (clickedEducation.length>0)
{
var caseEdu=[];
var lieuEdu='Education';
for (var j=0;j<clickedEducation.length;j++)
{
caseEdu[j]=clickedEducation[j];
var request = {
bounds: maCarte.getBounds(),
types: caseEdu[j] // IT DOESN'T WORK
};
console.log
service.radarSearch(request, function (results,status) {callbackExecute(results,status,callback,lieuEdu,caseEdu[j])}); // IT DOESN'T WORK
}

}



function callbackExecute(results,status,fonctionDeRetour,catPlace,typePlace)
{
fonctionDeRetour(results,status,catPlace,typePlace);
}



function callback(results, status, catPlace, typePlace)
{

if (status != google.maps.places.PlacesServiceStatus.OK)
{
alert(status); //Message d'alerte zéro résultat
return;
}

catLieu=catPlace;
typeLieu=typePlace;

for (var i = 0, result; result = results[i]; i++)
{
createMarker(result); // Créer un marqueur pour chaque résultat
}
catLieu="";

}
}


EDIT : I wrote "var caseEdu[];" but is not the source of my problem.

EDIT2 : The problem is resolved, thanks a lot Dr.Molle :)

Answer

At the moment when the radarSearch-callback will be executed, the outer loop already has been finished, j points behind the end of caseEdu.

Possible fix:

replace this line:

service.radarSearch(request, function (results,status) {callbackExecute(results,status,callback,lieuEdu,caseEdu[j])});

with....

(function(edu){
   service.radarSearch(request, 
                       function (results,status) {
                         callbackExecute(results, 
                                         status, 
                                         callback, 
                                         lieuEdu, 
                                         edu);
                       }); 
 })(caseEdu[j]);

....now the current item in the loop will be passed as argument


Demo:

var catLieu;
var typeLieu;
var education = ['school', 'university'];

function clearMaps() {
  var markers = maCarte.get('markers');

  markers.forEach(function(marker) {
    marker.setMap(null);
  });
  markers.clear();
}

function performSearch() {
  clearMaps();
  var i;

  var clickedEducation = [];
  for (i = 0; i < education.length; i++) {
    var checkEducation = document.getElementById(education[i])
    if (checkEducation.checked) {
      clickedEducation.push(education[i])
    }
  }

  if (clickedEducation.length > 0) {
    var caseEdu = [];
    var lieuEdu = 'Education';
    for (var j = 0; j < clickedEducation.length; j++) {
      caseEdu[j] = clickedEducation[j];
      var request = {
        bounds: maCarte.getBounds(),
        type: caseEdu[j] // IT DOESN'T WORK
      };
      (function(edu) {
        service.radarSearch(request, function(results, status) {
          callbackExecute(results, status, callback, lieuEdu, edu)
        });
      })(caseEdu[j]);
    }

  }



  function callbackExecute(results, status, fonctionDeRetour, catPlace, typePlace) {
    fonctionDeRetour(results, status, catPlace, typePlace);
  }



  function callback(results, status, catPlace, typePlace) {

    if (status != google.maps.places.PlacesServiceStatus.OK) {
      //alert(status); //Message d'alerte zéro résultat
      return;
    }

    catLieu = catPlace;
    typeLieu = typePlace;

    for (var i = 0, result; result = results[i]; i++) {
      createMarker(result); // Créer un marqueur pour chaque résultat
    }
    catLieu = "";

  }
}

function createMarker(result) {
  maCarte.get('markers').push(new google.maps.Marker({
    position: result.geometry.location,
    map: maCarte
  }))
}

function initialize() {


  var mapOptions = {
    zoom: 12,
    center: new google.maps.LatLng(52.5498783, 13.425209099999961),
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    noClear: true,
    markers: new google.maps.MVCArray
  };
  maCarte = new google.maps.Map(document.getElementById('map_canvas'),
    mapOptions);
  service = new google.maps.places.PlacesService(maCarte)
  maCarte.controls[google.maps.ControlPosition.TOP_CENTER]
          .push(document.getElementById('ctrl'));
  google.maps.event.addListenerOnce(maCarte,'idle',performSearch);
}

google.maps.event.addDomListener(window, 'load', initialize);
html,
       body,
       #map_canvas {
         height: 100%;
         margin: 0;
         padding: 0
       }
       label {
         display: block;
       }
       #ctrl {
         background: #fff;
       }
<div id="map_canvas">
  <div id="ctrl">
    <label for="school">
      <input id="school" type="checkbox" onchange="performSearch()" />school</label>
    <label for="university">
      <input checked  id="university" type="checkbox" onchange="performSearch()" />university</label>
  </div>
</div>
<script src="https://maps.googleapis.com/maps/api/js?v=3&libraries=places"></script>