1

I am trying to get the lat and long coordinates from a google maps API to eventually pass them into my getWeather() function. However, I keep getting a "404" error and my console log statements are not working. Any clue why? I have an API key and when I add that to the end of the tag it still doesn't work.

fiddle

Btw: here is where I pulled the code

var cityFormEl = document.querySelector("#city-form");
var cityInputEl = document.querySelector("#cityname");
var cityContainerEl = document.querySelector("#city-container")
var daysContainerEl = document.querySelector("#days-container");
var citySearchTerm = document.querySelector("#city-search-term");
pastCitiesButtonsEl = document.querySelector("#past-cities-buttons");

var getWeather = function(lat, lon) {
  //format the OpenWeather api url 
  var apiUrl = `https://api.openweathermap.org/data/2.5/onecall?lat=${lat}&lon=${lon}&appid=fb9174eee39da62906652ee7dd116b7c`
  //make a request to the url 
  fetch(apiUrl)
    .then(function(response) {
      // request was successful 
      if (response.ok) {
        response.json().then(function(data) {
          displayWeather(data, city)
        });
      } else {
        alert("Error: location not found!");
      }
    })
    .catch(function(error) {
      alert("Unable to connect to weather app");
    });
};

function initialize(event) {
  event.preventDefault();
  var address = cityInputEl
  var autocomplete = new google.maps.places.Autocomplete(address);
  autocomplete.setTypes(['geocode']);
  google.maps.event.addListener(autocomplete, 'place_changed', function() {
    var place = autocomplete.getPlace();
    if (!place.geometry) {
      return;
    }
    var address = '';
    if (place.address_components) {
      address = [
        (place.address_components[0] && place.address_components[0].short_name || ''),
        (place.address_components[1] && place.address_components[1].short_name || ''),
        (place.address_components[2] && place.address_components[2].short_name || '')
      ].join(' ');
    }
  });
}

function codeAddress() {
  geocoder = new google.maps.Geocoder();
  var address = cityInputEl.value;
  geocoder.geocode({
    'address': address
  }, function(results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
      console.log("Latitude: " + results[0].geometry.location.lat());
      console.log("Longitude: " + results[0].geometry.location.lng());
    } else {
      console.log("Geocode was not successful for the following reason: " + status);
    }
  });
}
google.maps.event.addDomListener(window, 'load', initialize);
:root {
  --primary: #ccdad1;
  --secondary: #9caea9;
  --tertiary: #788585;
  --light-dark: #6f6866;
  --dark: #38302e;
  --border-radius: .3rem;
}

* {
  box-sizing: border-box;
}

body {
  background-color: var(--primary);
  margin: 0;
  padding: 0;
  font-family: "IBM Plex Sans", sans-serif;
  color: var(--dark);
  line-height: 1.5;
  font-size: 16px;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  font-weight: 700;
  margin: 0;
  color: var(--dark);
  line-height: 1.25;
}

main {
  margin: 20px auto;
  width: 94%;
}

p {
  font-size: 1.2rem;
}

.btn {
  font-size: 1.3rem;
  text-decoration: none;
  padding: 6px 5px;
  width: 100%;
  display: block;
  margin: 5px 0;
  border-radius: var(--border-radius);
  color: var(--primary);
  border: none;
  outline: none;
  background-color: var(--light-dark);
  box-shadow: 3px 3px var(--dark);
  transform: translate(-1px, -1px);
}

.btn:hover {
  color: var(--primary);
  background-color: var(--tertiary);
  transform: translate(0, 0);
  box-shadow: 2px 2px var(--dark);
}

.btn-inline {
  display: inline;
}

.btn-back {
  border-radius: var(--border-radius);
  color: var(--primary);
  border: none;
  outline: none;
  background-color: var(--light-dark);
  box-shadow: 3px 3px var(--secondary);
  transform: translate(-1px, -1px);
  display: inline-block;
  width: auto;
  margin-top: 20px;
  padding: 15px;
  text-decoration: none;
  font-size: 1.2rem;
}

.btn-back:hover {
  color: var(--primary);
  background-color: var(--tertiary);
  transform: translate(0, 0);
  box-shadow: 2px 2px var(--dark);
}

.hero {
  padding: 3% 4%;
  background-color: var(--dark);
  color: var(--primary);
}

.hero p {
  max-width: 75%;
}

.app-title {
  font-size: 3rem;
  background-color: var(--primary);
  color: var(--dark);
  padding: 0 10px;
  display: inline-block;
  border-radius: var(--border-radius);
  box-shadow: 6px 5px var(--light-dark);
}

.list-group {
  padding: 0;
  list-style: none;
}

.list-item {
  margin-bottom: 10px;
  padding: 1.5%;
  border-radius: var(--border-radius);
  background-color: var(--light-dark);
  color: var(--primary);
  text-decoration: none;
}

.list-item:hover {
  background-color: var(--dark);
}


/* .status-icon {
    padding: 2px 5px;
    margin: 0 5px;
    background-color: rgba(255,255,255, 1);
    border-radius: var(--border-radius);
  }
  
  .icon-danger {
    color: rgb(255, 70, 70);
  }
  
  .icon-success {
    color: rgb(29, 153, 255);
  } */


/* CARDS */

.card {
  margin: 0 0 20px 0;
  border: 3px solid var(--dark);
  border-radius: var(--border-radius);
}

.card-header {
  color: var(--primary);
  background-color: var(--dark);
  padding: 2.5%;
  border-radius: calc(.18rem - 1px) calc(.18rem - 1px) 0 0;
}

.card-body {
  padding: 2.5%;
}

.day-card {
  width: 20%;
}


/* FORM */

.form-label,
.form-input,
.form-textarea {
  display: block;
}

.form-label {
  font-size: 1.1rem;
  margin: 0 0 0 5px;
}

.form-input {
  width: 100%;
  padding: 3%;
  margin: 5px 0;
  font-size: 1.2rem;
  border: 2px solid var(--light-dark);
  border-radius: var(--border-radius);
}


/* HEIGHT / WIDTH UTILS */

.min-100-vh {
  min-height: 100vh;
}

.min-100-vw {
  min-width: 100vw;
}


/* FONT UTILS */

.text-uppercase {
  text-transform: uppercase;
}


/* FLEX CONTENT */

.flex-row {
  display: flex;
  flex-wrap: wrap;
}

.flex-column {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
}

.justify-space-between {
  justify-content: space-between;
}

.justify-space-around {
  justify-content: space-around;
}

.justify-flex-start {
  justify-content: flex-start
}

.justify-flex-end {
  justify-content: flex-end;
}

.justify-center {
  justify-content: center;
}

.align-stretch {
  align-items: stretch;
}

.align-end {
  align-items: flex-end;
}

.align-center {
  align-items: center;
}

.col-auto {
  flex-grow: 1;
}

.col-1 {
  flex: 0 0 calc(100% * 1 / 12 - 2%);
}

.col-2 {
  flex: 0 0 calc(100% * 2 / 12 - 2%);
}

.col-3 {
  flex: 0 0 calc(100% * 3 / 12 - 2%);
}

.col-4 {
  flex: 0 0 calc(100% * 4 / 12 - 2%);
}

.col-5 {
  flex: 0 0 calc(100% * 5 / 12 - 2%);
}

.col-6 {
  flex: 0 0 calc(100% * 6 / 12 - 2%);
}

.col-7 {
  flex: 0 0 calc(100% * 7 / 12 - 2%);
}

.col-8 {
  flex: 0 0 calc(100% * 8 / 12 - 2%);
}

.col-9 {
  flex: 0 0 calc(100% * 9 / 12 - 2%);
}

.col-10 {
  flex: 0 0 calc(100% * 10 / 12 - 2%);
}

.col-11 {
  flex: 0 0 calc(100% * 11 / 12 - 2%);
}

.col-12 {
  flex: 0 0 100%;
}


/* col-sm */

@media screen and (min-width: 640px) {
  .col-sm-1 {
    flex: 0 0 calc(100% * 1 / 12 - 2%);
  }
  .col-sm-2 {
    flex: 0 0 calc(100% * 2 / 12 - 2%);
  }
  .col-sm-3 {
    flex: 0 0 calc(100% * 3 / 12 - 2%);
  }
  .col-sm-4 {
    flex: 0 0 calc(100% * 4 / 12 - 2%);
  }
  .col-sm-5 {
    flex: 0 0 calc(100% * 5 / 12 - 2%);
  }
  .col-sm-6 {
    flex: 0 0 calc(100% * 6 / 12 - 2%);
  }
  .col-sm-7 {
    flex: 0 0 calc(100% * 7 / 12 - 2%);
  }
  .col-sm-8 {
    flex: 0 0 calc(100% * 8 / 12 - 2%);
  }
  .col-sm-9 {
    flex: 0 0 calc(100% * 9 / 12 - 2%);
  }
  .col-sm-10 {
    flex: 0 0 calc(100% * 10 / 12 - 2%);
  }
  .col-sm-11 {
    flex: 0 0 calc(100% * 11 / 12 - 2%);
  }
  .col-sm-12 {
    flex: 0 0 100%;
  }
}


/* col-md */

@media screen and (min-width: 768px) {
  .col-md-1 {
    flex: 0 0 calc(100% * 1 / 12 - 2%);
  }
  .col-md-2 {
    flex: 0 0 calc(100% * 2 / 12 - 2%);
  }
  .col-md-3 {
    flex: 0 0 calc(100% * 3 / 12 - 2%);
  }
  .col-md-4 {
    flex: 0 0 calc(100% * 4 / 12 - 2%);
  }
  .col-md-5 {
    flex: 0 0 calc(100% * 5 / 12 - 2%);
  }
  .col-md-6 {
    flex: 0 0 calc(100% * 6 / 12 - 2%);
  }
  .col-md-7 {
    flex: 0 0 calc(100% * 7 / 12 - 2%);
  }
  .col-md-8 {
    flex: 0 0 calc(100% * 8 / 12 - 2%);
  }
  .col-md-9 {
    flex: 0 0 calc(100% * 9 / 12 - 2%);
  }
  .col-md-10 {
    flex: 0 0 calc(100% * 10 / 12 - 2%);
  }
  .col-md-11 {
    flex: 0 0 calc(100% * 11 / 12 - 2%);
  }
  .col-md-12 {
    flex: 0 0 100%;
  }
}


/* col-lg */

@media screen and (min-width: 992px) {
  .col-lg-1 {
    flex: 0 0 calc(100% * 1 / 12 - 2%);
  }
  .col-lg-2 {
    flex: 0 0 calc(100% * 2 / 12 - 2%);
  }
  .col-lg-3 {
    flex: 0 0 calc(100% * 3 / 12 - 2%);
  }
  .col-lg-4 {
    flex: 0 0 calc(100% * 4 / 12 - 2%);
  }
  .col-lg-5 {
    flex: 0 0 calc(100% * 5 / 12 - 2%);
  }
  .col-lg-6 {
    flex: 0 0 calc(100% * 6 / 12 - 2%);
  }
  .col-lg-7 {
    flex: 0 0 calc(100% * 7 / 12 - 2%);
  }
  .col-lg-8 {
    flex: 0 0 calc(100% * 8 / 12 - 2%);
  }
  .col-lg-9 {
    flex: 0 0 calc(100% * 9 / 12 - 2%);
  }
  .col-lg-10 {
    flex: 0 0 calc(100% * 10 / 12 - 2%);
  }
  .col-lg-11 {
    flex: 0 0 calc(100% * 11 / 12 - 2%);
  }
  .col-lg-12 {
    flex: 0 0 100%;
  }
}


/* col-xl */

@media screen and (min-width: 1200px) {
  .col-xl-1 {
    flex: 0 0 calc(100% * 1 / 12 - 2%);
  }
  .col-xl-2 {
    flex: 0 0 calc(100% * 2 / 12 - 2%);
  }
  .col-xl-3 {
    flex: 0 0 calc(100% * 3 / 12 - 2%);
  }
  .col-xl-4 {
    flex: 0 0 calc(100% * 4 / 12 - 2%);
  }
  .col-xl-5 {
    flex: 0 0 calc(100% * 5 / 12 - 2%);
  }
  .col-xl-6 {
    flex: 0 0 calc(100% * 6 / 12 - 2%);
  }
  .col-xl-7 {
    flex: 0 0 calc(100% * 7 / 12 - 2%);
  }
  .col-xl-8 {
    flex: 0 0 calc(100% * 8 / 12 - 2%);
  }
  .col-xl-9 {
    flex: 0 0 calc(100% * 9 / 12 - 2%);
  }
  .col-xl-10 {
    flex: 0 0 calc(100% * 10 / 12 - 2%);
  }
  .col-xl-11 {
    flex: 0 0 calc(100% * 11 / 12 - 2%);
  }
  .col-xl-12 {
    flex: 0 0 100%;
  }
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link href="https://fonts.googleapis.com/css?family=IBM+Plex+Sans:400,400i,700&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css">
  <link rel="stylesheet" href="assets/css/style.css" />
  <title>Weather Dashboard</title>
</head>

<body class="flex-column min-100-vh">
  <header class="hero">
    <h1 class="app-title">Weather Dashboard</h1>
  </header>
  <main class="flex-row justify-space-between">
    <div class="col-12 col-md-4">
      <div class="card">
        <h3 class="card-header text-uppercase">Search for a City:</h3>
        <form id="city-form" class="card-body">
          <label class="form-label">City Name</label>
          <input name="cityname" id="cityname" type="text" autofocus="true" class="form-input" />
          <button id="getCords" class="btn" onClick="codeAddress();">Search</button>
        </form>
      </div>
      <div class="card">
        <h3 class="card-header text-uppercase">Recent Searches </h3>
        <div class="card-body" id="past-cities-buttons">
          <button class="btn" data-past-cityname="past-cityname">Past City Name</button>
        </div>
      </div>
    </div>
    <!-- current forecast-->
    <div class="col-12 col-md-8">
      <div id="city-container" class="card">
        <h2 class="subtitle">City Name and Date <span id="city-search-term"></span></h2>
        <p>Temp:</p>
        <p>Wind:</p>
        <p>Humidity:</p>
        <p>UV Index:</p>
      </div>
      <!-- 5 day forecast -->
      <div id="days-container" class="list-group"></div>
      <h2 class="subtitle">5-Day Forecast: <span id="5-day-forcast"></span></h2>
      <div class="card day-card">
        <h3 class="card-header text-uppercase">Date</h3>
        <div class="card-body">
          <p>Weather icon image</p>
          <p>Temp:</p>
          <p>Wind:</p>
          <P>Humidity</P>
        </div>
      </div>
    </div>
  </main>
  <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places"></script>
  <script src=" assets/js/script.js"></script>
</body>

</html>
  • 1
    The button you click to `search` is, by default, a `submit` button which will submit the form using GET. Is this your intended behaviour? Reloading the page but not using the querystring parameters sort of negates the whole process. The only encountered 404 error I saw when running your fiddle refers to the script.js and styles.css – Professor Abronsius Jan 15 '22 at 11:24
  • I had a little play with this code and made [a different fiddle](https://jsfiddle.net/RamRaider/9v4oxje2/3/) into which you can add your own API key to test?! – Professor Abronsius Jan 15 '22 at 11:30
  • Thank you so much! I am looking at your fiddle to try and learn your process. Would you mind explaining why you did "const _EXPIRY=Math.pow( 60, 2 ) * 10; //10 minutes" I don't know what "not stale" means –  Jan 15 '22 at 23:21
  • also if you would like to post your comments as the answer I can select it as the chosen solution and you will earn stack points –  Jan 15 '22 at 23:22
  • The responses from the Weather API are stored in a global variable for 10minutes. If you click on one of the `previous search` links below the input field to re-select a city/location rather than run the same query to return the same data ( unlikely the weather data changes much in 10 mins or so ) the local variable is used instead. After 10mins ( or whatever ) if you once again query for a previously selected city/location the data in the local variable will be updated. This is really just a means of limiting hits to the api. You could alternatively store the data in `sessionStorage`s. – Professor Abronsius Jan 16 '22 at 06:58
  • As for what `const _EXPIRY=Math.pow( 60, 2 ) * 10;` actually does... well it was supposed to be 10mins but I made a mistake there and it should have been(or be) `Math.pow( 10, 4 ) * 60` ~ or 600,000ms! – Professor Abronsius Jan 16 '22 at 06:58
  • I used `Non-Stale` and `Fresh` to identify which data was being used. If the data comes from the cache it is considered new enough to use, thus `Non-Stale` – Professor Abronsius Jan 16 '22 at 07:07
  • Thank you so much for explaining it all! That makes a lot of sense. Happy coding :) –  Jan 16 '22 at 23:46
  • I'd be interested to see how you have developed upon this initial state for this app – Professor Abronsius Jan 19 '22 at 09:38
  • 1
    Sure! You can check out the deployed app from the link in the README.md https://github.com/K-G-J/weather-dashboard –  Jan 20 '22 at 20:25
  • Thanks for that @Kate ~ looking good so far. I see you employed the idea of caching the search parameters but not the actual data though... could easily assign the response data into that storage and fetch from that ~ but you have managed to keep your code/app much simpler than what I ended up creating :-) – Professor Abronsius Jan 20 '22 at 22:35
  • thank you! next one I make I will likely use fresh and stale like you did but this app was simple so the API requests didn't need to expire –  Jan 21 '22 at 01:47

0 Answers0