Search code examples
javascriptbing-mapsbingbing-api

How to check if data is already in array in javascript?


I am working on a JavaScript project using Bing-Maps API. The goal of the project is to search for businesses in user's area, and then print their names and phone numbers on the screen. Bing has a limitation of 25 searches per specific area, so I have to constantly move target square so it will get new results. Problem is, very often target squares overlap, and website adds same businesses that it already added before into array. I tried to use almost every javascript function to check for duplicate in array, but no matter what, it keeps adding duplicates into array and there is nothing to stop it.

function GeocodeCallback(response) {
  var output = document.getElementById('output');
  let used = [] //Array for posted numbers

  //Chech if phone number has been already posted
  function HasDuplicate(object) {
    for (let i = 0; i < used.length; i++) {
      if (used[i] == object) {
        return true
      }
    }
    return false
  }

  if (response &&
    response.resourceSets &&
    response.resourceSets.length > 0 &&
    response.resourceSets[0].resources) {

    var results = response.resourceSets[0].resources;

    let html = ['<table>'];
    //PROBLEM AREA ----------------------------------------------------------------------------------------
    for (var i = 0; i < results.length; i++) {
      console.log("Phone " + results[i].PhoneNumber + "Name " + results[i].name)
      if (!HasDuplicate(results[i].PhoneNumber)) {
        console.log("Not Duplicate")
        html.push('<tr><td>' + results[i].name + '</td><td>' + results[i].PhoneNumber + '</td></tr>'); //<td>', results[i].Website, '</td>
        data += results[i].PhoneNumber + " , " + results[i].name + "\n" //Save Data into file
        used.push(results[i].PhoneNumber)
      } else {
        console.log("IsDuplicate " + results[i].name)
      }
    }
    //PROBLEM AREA ----------------------------------------------------------------------------------------
    html.push('</table>');
    output.innerHTML += html.join('');
  } else {
    output.innerHTML = "No results found.";
  }
}

When I run this code, 99% of the numbers that it prints it says are not duplicates even though they are, but there is 1% of phone numbers that are marked as duplicates and are not added to array. So my code is able to detect if it's a duplicate or not, but it doesn't do it 100% of the time for some reason. Am I doing the check wrong or is it a problem with Bing Maps Data ?

Here is my full code if you would like to try to replicate the issue. Thank you for your time reading this post, any help will be appreciated.

var map, searchManager;
var BingMapsKey = 'AuV6Kc6hF3yFNL_DXFTDGuSu9DCdIK8zYF208z0eNdqbXtt87UHslIKJ70900Wbj';
let data = "" //String to store data that will be saved 
let userLat, userLong, updatedLat, updatedLong

function GetMap() {
  map = new Microsoft.Maps.Map('#myMap', {
    credentials: BingMapsKey
  });

  //Load the spatial math module
  Microsoft.Maps.loadModule("Microsoft.Maps.SpatialMath", function() {
    //Request the user's location
    navigator.geolocation.getCurrentPosition(function(position) {
      var loc = new Microsoft.Maps.Location(position.coords.latitude, position.coords.longitude);
      userLat = position.coords.latitude
      userLong = position.coords.longitude
      updatedLat = userLat + 0.05
      updatedLong = userLong + 0.05
      geocode()
      //Create an accuracy circle
      var path = Microsoft.Maps.SpatialMath.getRegularPolygon(loc, position.coords.accuracy, 36, Microsoft.Maps.SpatialMath.Meters);
      var poly = new Microsoft.Maps.Polygon(path);
      map.entities.push(poly);

      //Add a pushpin at the user's location.
      var pin = new Microsoft.Maps.Pushpin(loc);
      map.entities.push(pin);

      //Center the map on the user's location.
      map.setView({
        center: loc,
        zoom: 17
      });
    });
  });
}



function geocode() {
  var query = document.getElementById('input').value;

  //Move around the map and get locations from specific square
  for (let x = 0; x < 10; x++) {
    const longlat = [userLat, userLong, updatedLat, updatedLong]
    var geocodeRequest = "http://dev.virtualearth.net/REST/v1/LocalSearch/?query=" + encodeURIComponent(query) + "&userMapView=" + encodeURIComponent(longlat) + "&maxResults=25&jsonp=GeocodeCallback&key=" + BingMapsKey;
    CallRestService(geocodeRequest, GeocodeCallback);
    userLat += 0.05
    userLong += 0.05
    updatedLat += 0.05
    updatedLong += 0.05
  }
}

function GeocodeCallback(response) {
  var output = document.getElementById('output');
  let used = [] //Array for posted numbers

  //Chech if phone number has been already posted
  function HasDuplicate(object) {
    for (let i = 0; i < used.length; i++) {
      if (used[i] == object) {
        return true
      }
    }
    return false
  }

  if (response &&
    response.resourceSets &&
    response.resourceSets.length > 0 &&
    response.resourceSets[0].resources) {

    var results = response.resourceSets[0].resources;

    let html = ['<table>'];
    //PROBLEM AREA ----------------------------------------------------------------------------------------
    for (var i = 0; i < results.length; i++) {
      console.log("Phone " + results[i].PhoneNumber + "Name " + results[i].name)
      if (!HasDuplicate(results[i].PhoneNumber)) {
        console.log("Not Duplicate")
        html.push('<tr><td>' + results[i].name + '</td><td>' + results[i].PhoneNumber + '</td></tr>'); //<td>', results[i].Website, '</td>
        data += results[i].PhoneNumber + " , " + results[i].name + "\n" //Save Data into file
        used.push(results[i].PhoneNumber)
      } else {
        console.log("IsDuplicate " + results[i].name)
      }
    }
    //PROBLEM AREA ----------------------------------------------------------------------------------------

    html.push('</table>');


    output.innerHTML += html.join('');


  } else {
    output.innerHTML = "No results found.";
  }
}

let WriteToFile = () => {

  // Convert the text to BLOB.
  const textToBLOB = new Blob([data], {
    type: 'text/plain'
  });
  const sFileName = 'formData.txt'; // The file to save the data.

  let newLink = document.createElement("a");
  newLink.download = sFileName;

  if (window.webkitURL != null) {
    newLink.href = window.webkitURL.createObjectURL(textToBLOB);
  } else {
    newLink.href = window.URL.createObjectURL(textToBLOB);
    newLink.style.display = "none";
    document.body.appendChild(newLink);
  }

  newLink.click();
}

function CallRestService(request) {
  var script = document.createElement("script");
  script.setAttribute("type", "text/javascript");
  script.setAttribute("src", request);
  document.body.appendChild(script);
}
#myMap {
  width: 600px;
  height: 600px;
  position: relative;
  margin: auto;
  width: 60%;
  padding: 10px;
}

#center {
  margin: auto;
  width: 60%;
  padding: 10px;
}

#search,
#output {
  margin-left: 20%;
}

.form-control {
  margin: 0 20%;
}

#space {
  margin-left: 17%;
}
<!DOCTYPE html>
<html>

<head>
  <title>Business Search</title>
  <meta charset="utf-8" />
  <link rel="stylesheet" href="style.css">
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4" crossorigin="anonymous"></script>
  <script src="script.js"></script>
  <script type='text/javascript' src='http://www.bing.com/api/maps/mapcontrol?callback=GetMap' async defer></script>
</head>

<body>
  <div id="myMap"></div>

  <h1 class="display-4" id="center">Search for business: </h1>

  <div class="input-group mb-3">
    <input type="text" id="input" class="form-control" value="car">
  </div>

  <button type="button" class="btn btn-outline-dark btn-large" id="search" value="Search" onClick="geocode()">Search</button>
  <button type="button" class="btn btn-outline-dark btn-large" value="Save" onClick="WriteToFile()">Save</button>

  <div id="output">Name<span id="space">Phone Number</span></div>
</body>

</html>


Solution

  • The array used to track the duplicates is being initialized repeatedly for every separate execution of your requests.

    function GeocodeCallback(response) {
      var output = document.getElementById('output');
      let used = [] //<------ This is initialized every time a new result set is arrived
      ...
    

    This means it is not going to track duplicates across multiple calls - because it always loses the numbers of the previous call.

    The array should be defined outside the callback:

    let used = [] //Array for posted numbers
    
    function GeocodeCallback(response) {
      var output = document.getElementById('output');
       ...