我必须单击两次搜索按钮才能从api获取数据

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我必须单击两次搜索按钮才能从api获取数据相关的知识,希望对你有一定的参考价值。

当我第一次单击搜索按钮时,它会出现两个错误:

  1. main.js:68获取https://cors-anywhere.herokuapp.com/https://api.darksky.net/forecast/API_key/ 404(未找到)
  2. 未捕获(在promise中)SyntaxError:位于0的JSON中的意外标记N.

但是当我第二次点击搜索按钮时,错误消失了。所以我必须单击两次搜索按钮才能从API获取数据。

的index.html

<form class="searchForm" method="POST">
    <div class="form-div">
        <label for="loaction">Enter a location</label>
        <input type="text" class="searchForm-input" id="loaction" placeholder="Location">
        <button type="submit">Search</button>
    </div>
</form>
<div class="echo">--</div>
<div class="location">
    <h1 class="location-timezone">Timezone</h1>
</div>
<div class="temperature">
    <div class="degree-section">
        <h2 class="temperature-degree">34</h2>

        <span>F</span>

    </div>
</div>

main.js

let lat1 = '';
let form = document.querySelector('.searchForm');
form.addEventListener('submit', handleSubmit);

function handleSubmit(event) {
    event.preventDefault();
    const input = document.querySelector('.searchForm-input').value;
    // remove whitespace from the input
    const searchQuery = input.split(' ').join('+');
    // print `searchQuery` to the console
    console.log(searchQuery);

    let geocodeURL = `https://maps.googleapis.com/maps/api/geocode/json? 
        address=${searchQuery}&key=api_key`;

    fetch(geocodeURL)
        .then(response => {
            return response.json();
        })
        .then(data => {

            let max = data.results[0].geometry.location;
            console.log(max);

            let max1 = max.lat + ',' + max.lng;
            console.log(max1);
            lat1 = max1;
            console.log(lat1);
        })
    console.log(geocodeURL);


    let temperatureDegree = document.querySelector('.temperature-degree');
    let locationTimezone = document.querySelector('.location-timezone');
    let echos = document.querySelector('.echo');
    echos.textContent = searchQuery;

    const proxy = 'https://cors-anywhere.herokuapp.com/';
    const api =
        `${proxy}https://api.darksky.net/forecast/aki_key/${lat1}`;

    fetch(api)
        .then(response => {
            return response.json();
        })
        .then(data => {
            console.log(data);
            const {temperature} = data.currently;
            temperatureDegree.textContent = temperature;

            locationTimezone.textContent = data.timezone;

        })
}
答案

您有两个异步操作,第二个需要使用第一个AJAX操作的结果继续:

fetch(geocodeURL)
        .then(response => {
            return response.json();
        })
        .then(data => {

          let max = data.results[0].geometry.location;
          console.log(max);

          let max1 = max.lat+',' + max.lng;
          console.log(max1);
           lat1 = max1; <-- lat1 is used in second AJAX call
          console.log(lat1);
        })
    console.log(geocodeURL);

有些行后来:

        const proxy = 'https://cors-anywhere.herokuapp.com/';
        const api = 
        `${proxy}https://api.darksky.net/forecast/aki_key/${lat1}`; // <-- lat1 will be undefined

因此,当您单击搜索按钮时,第一个将触发,当它返回时,它将填充lat1变量。因为这是Promise的结果,它会在它完成后立即触发,同时主线程将会继续并执行下一个fetch(api)语句而不等待lat1被设置。只需将第二个AJAX调用移动到Promise解析中:

event.preventDefault();
const input = document.querySelector('.searchForm-input').value;
// remove whitespace from the input
const searchQuery = input.split(' ').join('+');
// print `searchQuery` to the console
console.log(searchQuery);

let geocodeURL = `https://maps.googleapis.com/maps/api/geocode/json? 
address=${searchQuery}&key=api_key`;

fetch(geocodeURL)
            .then(response => {
                return response.json();
            })
            .then(data => {

                let max = data.results[0].geometry.location;
                console.log(max);

                let max1 = max.lat+',' + max.lng;
                console.log(max1);
                lat1 = max1;
                console.log(lat1);

                let temperatureDegree = document.querySelector('.temperature- 
                 degree');
                let locationTimezone = document.querySelector('.location-timezone');
                let echos = document.querySelector('.echo');
                echos.textContent = searchQuery;

                const proxy = 'https://cors-anywhere.herokuapp.com/';
                const api = 
                `${proxy}https://api.darksky.net/forecast/aki_key/${lat1}`;

                fetch(api)
                    .then(response => {
                        return response.json();
                    })
                    .then(data => {
                        console.log(data);
                        const {temperature} = data.currently;
                        temperatureDegree.textContent = temperature;

                        locationTimezone.textContent = data.timezone;

                    })
                }
            })
console.log(geocodeURL);

以上是关于我必须单击两次搜索按钮才能从api获取数据的主要内容,如果未能解决你的问题,请参考以下文章

在按钮单击时反应获取数据

为啥我需要单击两次才能在输入字段中生成一个值

为啥我需要在提交按钮上单击两次才能提交我的表单?

为啥我需要按两次后退按钮才能第一次关闭片段?

我必须单击两次才能让日期选择器显示

Kotlin:片段内的按钮需要在开始活动之前单击两次。如何一键启动活动?