简体   繁体   中英

I have to click the search button two times to get the data from api

When I click the search button for the first time it gives two errors:

  1. main.js:68 GET https://cors-anywhere.herokuapp.com/https://api.darksky.net/forecast/API_key/ 404 (Not Found)

  2. Uncaught (in promise) SyntaxError: Unexpected token N in JSON at position 0.

But when I click the search button second time the error goes away. so I have to click the search button two times to get the data from the 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;

        })
}

You have two asynchronous operations where the second needs to use the results of the first AJAX operation to continue:

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);

And some lines later:

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

So when you click the search button the first will fire and when it returns it will fill the lat1 variable. As this is the result of a Promise, it will fire as soon as it is fulfilled while in the meantime the main thread will contine and perform the next fetch(api) statement without waiting for the lat1 to be set. Simply move the second AJAX call into the Promise resolution:

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM