0

I wrote a JS script to receive nearest Street View positions for given points (latitude, longitude). I have a problem with (what seems to me) callback function.

Here's the code:

<html>
  <head>
    <meta charset="utf-8">
    <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

  </head>
  <body>
      <input type="file" id="file-input" />
      <h3>Contents of the file:</h3>
      <pre id="file-content"></pre>
    <div class="container">
      <div>gid,lat_from,lon_from</div>>
    </div>

    <script>

function readSingleFile(e) {
  var file = e.target.files[0];
  if (!file) {
    return;
  }
  var reader = new FileReader();
  reader.onload = function(e) {
    var contents = e.target.result;
    processFile(contents, returnFile)
    
  };

  reader.readAsText(file);
}

result = "";


function processFile(contents, callback) {
  var text = contents
  var splitted = text.split('\r\n')

  splitted.forEach(function(point) {
    var gid = point.split(';')[0]
    var latilong = point.split(';')[1].replace(/[\ ]/g, '')
    var splitted2 = latilong.split(':')

    var lat = splitted2[1].split(',')[0]
    var lon = splitted2[2].split('}')[0]
    var latilong = new google.maps.LatLng(lat, lon);

    // alert(latilong)

    var radius = 20
    var streetViewService = new google.maps.StreetViewService();
    streetViewService.getPanoramaByLocation(latilong, radius, function(data, status)
      {
        if (status == google.maps.StreetViewStatus.OK)
        {
          var nearStreetViewLocation = data.location.latLng;
         
          result = result + gid + ', ' + JSON.stringify(nearStreetViewLocation).replace(/[\" \} \{ lat long \:]/g,'') + '</br>';
          $( ".container" ).append(result);
          $( ".container" ).append('<br/>');
        }
        else {
          $( ".container" ).append("<div> "+ gid + ', 0' + "</div>" );      
        }
          
        });
    });

  if (callback) {
      callback(result);
  }
}

function returnFile(results) {
  if(results) {
   $( ".container" ).append('<br/> from callback function: </br>');
   $( ".container" ).append(results);
  } else {
   alert('results is null');
  }
}


document.getElementById('file-input')
  .addEventListener('change', readSingleFile, false);
      
       </script>
  </body>
</html>

You can run the script with a given text file as an example:

7512 ; {lat:52.2254802729, lon:21.0105694375}
7513 ; {lat:52.2254556313, lon:21.0104179005}
7563 ; {lat:52.2245593608, lon:21.0063570311}

As you can see the results variable in returnFile function is empty (alert that results is null). It is not empty in processFile function (incrementing content is displayed in ".container") and it's passed in the processFile function to returnFile function.

How can it be fixed? I thought that such callback will be enough to pass a non-empty variable from a processFile function.

I would like to process the result variable in returnFile function after filling it inside processFile.

Cheers!

James Ch
  • 25
  • 4

1 Answers1

0

Seems like I solved this by using counter in forEach (as said there: Callback after all asynchronous forEach callbacks are completed ) and here's the code:

<html>
  <head>
    <meta charset="utf-8">
    <title>Directly accessing Street View data</title>
    <style>
      html, body, #map-canvas {
        height: 100%;
        margin: 0px;
        padding: 0px
      }
    </style>
    <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

  </head>
  <body>
      <input type="file" id="file-input" />
      <h3>Contents of the file:</h3>
      <pre id="file-content"></pre>
    <div class="container">
      <div>gid,lat_from,lon_from</div>>
    </div>

    <script>

function readSingleFile(e) {
  var file = e.target.files[0];
  if (!file) {
    return;
  }
  var reader = new FileReader();
  reader.onload = function(e) {
    var contents = e.target.result;
    processFile(contents, returnFile)
    
  };

  reader.readAsText(file);
}

result = "";


function processFile(contents, callback) {
  var text = contents
  var splitted = text.split('\r\n')
  $( ".container" ).append("splitted length: " + splitted.length + "<br>");
  var itemsProcessed = 0;

  splitted.forEach(function(point) {
    var gid = point.split(';')[0]
    var latilong = point.split(';')[1].replace(/[\ ]/g, '')
    var splitted2 = latilong.split(':')

    var lat = splitted2[1].split(',')[0]
    var lon = splitted2[2].split('}')[0]
    var latilong = new google.maps.LatLng(lat, lon);

    // alert(latilong)

    var radius = 20
    var streetViewService = new google.maps.StreetViewService();
    streetViewService.getPanoramaByLocation(latilong, radius, function(data, status)
      {
        itemsProcessed++;
        if (status == google.maps.StreetViewStatus.OK)
        {
          var nearStreetViewLocation = data.location.latLng;
          // alert(nearStreetViewLocation)
          // $( ".container" ).append("<div> "+ gid + ', ' + JSON.stringify(nearStreetViewLocation).replace(/[\" \} \{ lat long \:]/g,'') +"</div>" );  
          // console.log(gid + ', ' + JSON.stringify(nearStreetViewLocation).replace(/[\" \} \{ lat long \:]/g,''))          
          result = result + gid + ', ' + JSON.stringify(nearStreetViewLocation).replace(/[\" \} \{ lat long \:]/g,'') + '<br>';
          $( ".container" ).append(result);
          $( ".container" ).append('<br/>');
          $( ".container" ).append("items processed: " + itemsProcessed);
          if(itemsProcessed === splitted.length) {
            callback(result);
          }
        }
        else {
          $( ".container" ).append("<div> "+ gid + ', 0' + "</div>" );      
        }
          
      });
    });

  // if (callback) {
  //     callback(result);
  // }
}

function returnFile(results) {
  if(results) {
    alert('results is not null');
   $( ".container" ).append('<br/> from callback function: </br>');
   $( ".container" ).append(results);
  } else {
   alert('results is null');
  }
}


document.getElementById('file-input')
  .addEventListener('change', readSingleFile, false);

      //  points5 = [{lat:52.2254802729, lng:21.0105694375},
      // {lat:52.2254556313, lng:21.0104179005},
      // {lat:52.2245593608, lng:21.0063570311},
      // {lat:52.2245355399, lng:21.0062524214},
      // {lat:52.2245125335, lng:21.0061437961}];
      
      // // points5.forEach(function(point) {
      // //   $( ".container" ).append("<div>"+ JSON.stringify(point, null).replace(/\"/g,'') +"</div>" );
      // // });
      // var radius = 20
      // var streetViewService = new google.maps.StreetViewService();
      // points5.forEach(function(point) {
      //   streetViewService.getPanoramaByLocation(point, radius, function(data, status)
      //   {
      //       if (status == google.maps.StreetViewStatus.OK)
      //       {
      //         var nearStreetViewLocation = data.location.latLng;
      //         alert(nearStreetViewLocation)
      //         $( ".container" ).append("<div>"+ JSON.stringify(nearStreetViewLocation).replace(/[\" \} \{ lat long \:]/g,'') +"</div>" );            
      //         return nearStreetViewLocation
      //       }
      //       else {
      //         alert("error")
      //       }
      //   });
      // });
      
      
       </script>
  </body>
</html>
James Ch
  • 25
  • 4