ForLoop调用仅功能一次

时间:2020-09-14 23:15:11

标签: javascript function for-loop

我有一个fourLoop,它调用我的函数addMarker,但是我只得到一个循环的结果。我嵌套在循环中的控制台日志返回正确的数组长度。我对此问题感到好奇,因为我怀疑我对某些概念缺乏关注。这是针对Google地图,地点和地理编码API的(出于安全考虑,我删除了我的密钥,因此,如果您仅阅读initMap函数,则所有相关问题均位于该范围内)。

更新:我记录了“ loopData”,并且得到了正确的迭代次数,但它只是最后一个索引中的数据。这使我朝着错误出现在forLoop中,在该错误中我解析了初始响应从Google place API。那里的代码是这样的: (下面的代码块的目的是迭代对象数组,并在每次迭代中获取某些值,并将这些值推到收集到的对象的新数组“ placesDataLocations”。现在,我得到的是正确的数量个对象,但每个对象的值都与我的API响应数据中的LAST合格对象完全相同。)

const gym = {}
const placesDataLocations = []

for (let i = 0; i < placesData.results.length; i++) {
  if (placesData.results[i].business_status === 'OPERATIONAL') {
    // Array of Objects in form {gym: {id: 10, quantity: 10} }
    gym.location = placesData.results[i].geometry.location
    gym.name = placesData.results[i].name
    gym.address = placesData.results[i].vicinity
    placesDataLocations.push({ gym: gym })
  }
}
console.log(placesDataLocations)
initMap(googleGeocodeLat, googleGeocodeLng, placesDataLocations)

})

初始API响应数据如下所示: enter image description here

UPDATE2:因此,我放弃了创建新对象数组的第一种方法,并尝试使用.map方法,如下所示:

const placesDataLocations = []
  for (let i = 0; i < placesData.results.length; i++) {
    if (placesData.results[i].business_status === 'OPERATIONAL') {
      placesDataLocations.push({ 
        placesData.results[i].map(data => {
        return {
          location: data.geometry.location,
          name: data.name,
          address: data.vicinity
        }
  })
 }) 
}

} 现在,控制台告诉我“ placesData.results [i] .map”不是一个函数。有人可以看到我在做什么错吗?

const mapModal = document.querySelector('#googleMap')
const originalMapContent = mapModal.innerHTML

// displaying the map
function initMap (locationLatitude, locationLongitude, gymCoordinates) {
  // Map options
  const options = {
    center: { lat: locationLatitude, lng: locationLongitude },
    zoom: 10
  }

  // New map
  const map = new google.maps.Map(document.getElementById('googleMap'), options)

  // Add markers
  const marker = new google.maps.Marker({
    position: { lat: locationLatitude, lng: locationLongitude },
    map: map
  // icon: '...'
  })

  // const coordinates = gymCoordinates
  for (let i = 0; i < gymCoordinates.length; i++) {
    console.log(gymCoordinates.length);
    addMarker(gymCoordinates[i])
  }

  // Add marker function - displays multiple different markers
  function addMarker (loopData) {
    const marker = new google.maps.Marker({
      position: loopData.gym.location,
      map: map,
      icon: 'https://img.icons8.com/offices/2x/map-pin.png'
    })
    
    // Add infoWindow
    const infoWindowContent = `<h6>${loopData.gym.name}</h6><div>${loopData.gym.address}</div>`
    const infoWindow = new google.maps.InfoWindow({

      content: infoWindowContent
    })

    // Function required to display the info window on map
    marker.addListener('click', () => {
      infoWindow.open(map, marker)
    })
  }
}

const apiKey = '&key=key-removed'

const searchButton = document.getElementById('gymFind')

searchButton.addEventListener('click', async function (e) {
  e.preventDefault()

  // getting the zip code input
  const zipCode = document.querySelector('#userZip').value.trim()
  const googleGeocodeAPI = `https://maps.googleapis.com/maps/api/geocode/json?address=${zipCode},US${apiKey}`

  // call to API to grab latitude and longitude from the zip code user input
  const res = await fetch(googleGeocodeAPI)
    .catch(error => console.error({ error }))

  const data1 = await res.json()

  const googleGeocodeLat = data1.results[0].geometry.location.lat
  const googleGeocodeLng = data1.results[0].geometry.location.lng

  // console.log(lat, lng)

  // Google Places API requires Proxy server header to enable cross-origin-resource-sharing (CORS)
  var corsProxy = 'https://cors-anywhere.herokuapp.com/'

  const googlePlacesAPI = `${corsProxy}https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${googleGeocodeLat},${googleGeocodeLng}&radius=4500&type=gym&keyword=exercise${apiKey}`

  // call to API where list of gyms is generated using latitude and longitude of zip code
  const res2 = await fetch(googlePlacesAPI)
    .catch(error => console.error({ error }))

  const placesData = await res2.json()

  console.log(placesData)
  const gym = {}
  const placesDataLocations = []

  for (let i = 0; i < placesData.results.length; i++) {
    if (placesData.results[i].business_status === 'OPERATIONAL') {
      // Array of Objects in form {gym: {id: 10, quantity: 10} }
      gym.location = placesData.results[i].geometry.location
      gym.name = placesData.results[i].name
      gym.address = placesData.results[i].vicinity
      placesDataLocations.push({ gym: gym })
    }
  }
  console.log(placesDataLocations)
  initMap(googleGeocodeLat, googleGeocodeLng, placesDataLocations)
})

const modalCloseButton = document.querySelector('#modal-close-button')

// clearing the contents of the map modal on close to prepare for the next query
modalCloseButton.addEventListener('click', function (e) {
  e.preventDefault()
  mapModal.innerHTML = originalMapContent
})
<!DOCTYPE html>
<html>
  <head>
    <!--Import Google Icon Font-->
    <link
      href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet"
    />
    <!--Import materialize.css-->
    <link
      type="text/css"
      rel="stylesheet"
      href="assets/css/materialize.min.css"
      media="screen,projection"
    />
    <link type="text/css" rel="stylesheet" href="assets/css/main.css" />
    <script
      defer
      src="https://use.fontawesome.com/releases/v5.8.1/js/all.js"
      integrity="sha384-g5uSoOSBd7KkhAMlnQILrecXvzst9TdC09/VM+pjDTCM+1il8RHz5fKANTFFb+gQ"
      crossorigin="anonymous"
    ></script>
    <style>
      .section .card-image #foodImg {
        height: 200 pX;
        width: 100%;
      }
    </style>

    <!--Let browser know website is optimized for mobile-->
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Nutrition & Health</title>
  </head>

  <body id="home" class="scrollspy">

          <!-- SECTION Google Map and ZIP CODE-->
          <div id="gymFinder"  class="col s12 m4">
              <div class="card">
                  <div class="card-content">
                      <h3> <span class="card-title"><u>Let's Get Healthy</u></span></h3>
                      <p style="font-size:20px">Please enter your zip code for a map of work-out places in your area. </p>
                      <div class="input-field">
                          <input onkeyup="numbersOnly(this)" type="text" id="userZip"/>
                          <label for="userZip">Zip Code</label>
                        </div>

                  </div>
                  <div id="gymFind" class="card-action">
                    <a href="#mapmodal" class="btn waves-effect waves-light modal-trigger" id="map-button">Find A Gym</a>
                  </div>
                </div>
            </div>
            
          </div>
        </div>        
      </div>


          <div id="mapmodal" class="modal modal-fixed-footer">
              <div class="modal-content">
                  <div id="googleMap" style="width:100%;height:100%;"></div>
              </div>
              <div class="modal-footer">
                  <a id="modal-close-button" href="#" class="teal modal-action modal-close waves-effect waves-green btn">Close</a>
              </div>
          </div>

           <!-- SECTION: Footer-->

    <section class="section teal darken-2 white-text  ">
      <div class="container">
        Food Searcher&copy; 2019
      <a class="grey-text text-lighten-4 right" href="#!">Created by King Major</a>  
    </div> 
    </section>

    <!--Import jQuery before materialize.js-->
    <script
      type="text/javascript"
      src="https://code.jquery.com/jquery-3.2.1.min.js"
    ></script>
    <script src="https://www.gstatic.com/firebasejs/5.10.0/firebase.js"></script>
    <script type="text/javascript" src="assets/js/materialize.min.js"></script>
 
    <!-- External Scrips -->
    <script src="./assets/js/firebase.js"></script>
    <script src="./assets/js/restricted_login.js"></script>
    <script src="./assets/js/search.js"></script>

    <!-- Google Maps Scripts -->
    <script src="./assets/js/googlemap-test.js"></script>
    <script async defer src="https://maps.googleapis.com/maps/api/js?key=KEY-REMOVED&callback=initMap"></script>


    <!-- Internal Scripts -->
    <script>
      $(document).ready(function() {
        // Custom JS & jQuery here
        // INIT SIDENAVE
        $('.button-collapse').sideNav();
        // INIT SLIDER
        $('.slider').slider({
          indicators: false,
          height: 300,
          transition: 700,
          interval: 6000
        });
        
        
        //INIT SCROLLSPY
        $('.scrollspy').scrollSpy();
        // INIT SELECT MENU
        $('select').material_select();
        //INIT MODALS
        $('.modal').modal();
      });
    </script>
  </body>
</html>

1 个答案:

答案 0 :(得分:0)

您将在每次迭代中覆盖相同的对象,并将该对象推入数组。您需要一个全新的对象。

const placesDataLocations = []

for (let i = 0; i < placesData.results.length; i++) {
  if (placesData.results[i].business_status === 'OPERATIONAL') {
    // Array of Objects in form {gym: {id: 10, quantity: 10} }
    const gym = {
      location: placesData.results[i].geometry.location,
      name: placesData.results[i].name,
      address: placesData.results[i].vicinity
    }
    placesDataLocations.push({ gym: gym })
  }
}

如果要使用地图,则还必须循环使用过滤器。

const placesDataLocations = placesData.results
  .filter(function (result) {
    return result.business_status === 'OPERATIONAL';
  }).map( function(result) {
    return { 
      gym: {
        location: result.geometry.location,
        name: result.name,
        address: result.vicinity
      }
    }
  });