如何在自动完成输入上设置addEventListener并提供多个源回调并一一使用它们

问题描述 投票:0回答:1

我正在尝试在输入上设置

addEventListener
,当它发生变化时我想使用 fetch API 调用函数。 我有城市名称的自动完成输入,我的目标是通过选定的城市名称获取信息 其次,也许有人知道如何通过调用回调来优化这段代码,并一一使用它们,直到回调结果返回非空数组。

现在我输入了城市名称(通过 JSON API 获取),但控制台显示当我选择某个城市时输入值未定义。

我有js文件:

let cities = document.querySelector("#languageList");
let cityInfoContainer = document.querySelector(".cityInfoContainer");
let input = document.querySelector("#txtAutoComplete");



  fetch("https://katehrybkova.github.io/CItiesFilter/src/analytics/fixtures/cities.json")
  .then(res => res.json())
  .then((data) => {
     data.map(el=>cities.innerHTML += `<option value=${el.city}>`)
  })
  .catch(err => { throw err });
  

  let getCityInfo = (cityName) => fetch(`https://katehrybkova.github.io/CItiesFilter/src/analytics/fixtures/data/${cityName.toLowerCase()}`)
  .then(res => res.json())
  .then((data) => {
    data.map(city => city.map(el=>cityInfoContainer.innerHTML += `<p> ${el.year}</p>`))
  })
  .catch(err => { throw err });
  
  input.addEventListener("change", getCityInfo(this.value))

和 HTML

<body>
    <header></header>
    <main class="cityInfo">
        <form>
            <input type="text" id="txtAutoComplete" list="languageList" />
            <datalist id="languageList">
            </datalist>
        </form>
        <div class="cityInfoContainer"></div>

    </main>
    <footer></footer>
    <script src="./dist/main.js"></script>
</body>
javascript input callback fetch-api
1个回答
1
投票
  1. 您应该使用 Promises(或 async-await)
  2. 您忘记了城市信息 API 请求末尾的 .json
  3. .map() 返回一个新数组。您需要 .forEach() 此函数
  4. 只需要一个 .forEach() (所以不是地图中的地图),因为数组只有一层深

let cities = document.querySelector("#languageList");
let cityInfoContainer = document.querySelector(".cityInfoContainer");
let input = document.querySelector("#txtAutoComplete");

getCityNames()
  .then(data => {
    data.map(el => cities.innerHTML += `<option value=${el.city}>`)
  })

input.addEventListener("change", function(e) {
  getCityInfo(this.value)
    .then(data => {
      console.log(data)
      // this clears the area for the new city selected
      if (cityInfoContainer.innerHTML !== '') {
        cityInfoContainer.innerHTML = ''
      }
      data.forEach(city => cityInfoContainer.innerHTML += `<p> ${city.year} ${city.population}</p>`)
    })
    .catch(err => {
      console.log('err', err)
    })
})

function getCityNames() {
  return new Promise((resolve, rejecet) => {
    fetch("https://katehrybkova.github.io/CItiesFilter/src/analytics/fixtures/cities.json")
      .then(res => res.json())
      .then((data) => {
        resolve(data)
      })
      .catch(err => {
        reject(err)
      });
  })
}

function getCityInfo(cityName) {
  return new Promise((resolve, reject) => {
    fetch(`https://katehrybkova.github.io/CItiesFilter/src/analytics/fixtures/data/${cityName.toLowerCase()}.json`)
      .then(res => res.json())
      .then((data) => {
        resolve(data)
      })
      .catch(err => {
        reject(err)
      });
  })
}
<main class="cityInfo">
  <form>
    <input type="text" id="txtAutoComplete" list="languageList" />
    <datalist id="languageList">
            </datalist>
  </form>
  <div class="cityInfoContainer"></div>

</main>

至于一一调用,直到所有信息下载完毕:

let cities = document.querySelector("#languageList");
let cityInfoContainer = document.querySelector(".cityInfoContainer");
let input = document.querySelector("#txtAutoComplete");

// adding an array that will hold all the cities' names
let cityNameArr = []

getCityNames()
  .then(data => {
    data.forEach(el => cities.innerHTML += `<option value=${el.city}>`)
    return data.map(el => {
      return {
        cName: el.city
      }
    })
  })
  .then(cityNames => {
    return cityNames.map(el => {
      return {
        cName: el.cName,
        cInfo: getCityInfo(el.cName)
      }
    })
  })
  .then(city => {
    console.log(city) // expected to see "cInfo: Promise" - until it's resolved
  })



input.addEventListener("change", function(e) {
  getCityInfo(this.value)
    .then(data => {
      console.log(data)
      // this clears the area for the new city selected
      if (cityInfoContainer.innerHTML !== '') {
        cityInfoContainer.innerHTML = ''
      }
      data.forEach(city => cityInfoContainer.innerHTML += `<p> ${city.year} ${city.population}</p>`)
    })
    .catch(err => {
      console.log('err', err)
    })
})

function getCityNames() {
  return new Promise((resolve, rejecet) => {
    fetch("https://katehrybkova.github.io/CItiesFilter/src/analytics/fixtures/cities.json")
      .then(res => res.json())
      .then((data) => {
        resolve(data)
      })
      .catch(err => {
        reject(err)
      });
  })
}

function getCityInfo(cityName) {
  return new Promise((resolve, reject) => {
    fetch(`https://katehrybkova.github.io/CItiesFilter/src/analytics/fixtures/data/${cityName.toLowerCase()}.json`)
      .then(res => res.json())
      .then((data) => {
        resolve(data)
      })
      .catch(err => {
        reject(err)
      });
  })
}
<main class="cityInfo">
  <form>
    <input type="text" id="txtAutoComplete" list="languageList" />
    <datalist id="languageList">
            </datalist>
  </form>
  <div class="cityInfoContainer"></div>

</main>

© www.soinside.com 2019 - 2024. All rights reserved.