0

I am attempting to create a weather app as a way to learn how to code. I have designed the app myself and followed a tutorial for the JavaScript, but I encountered a 400 error when using the OpenWeather API. Here is my code:

const searchbar = document.querySelector('#search-bar');
const temperature = document.querySelector('.temperature');
const description = document.querySelector('.description');
const imageContainer = document.querySelector('.image-container');
const API_KEY = '<MY_API_KEY>';
const apiURL = `https://api.openweathermap.org/data/2.5/weather?q=${searchbar.value}&units=metric&appid=${API_KEY}`;

document.querySelector('form').addEventListener('submit', (e) => {
  e.preventDefault();
 
  fetch(apiURL);
});

async function getWeather() { 
  const response = await fetch(apiURl);
  const data = await response.json();
  console.log(data);
}

What can I do to resolve the 400 error?

Agrim Singh
  • 499
  • 2
  • 13
  • 3
    You probably shouldn't post your `API_KEY` values here... – Dai Jun 16 '23 at 03:03
  • 2
    You need to percent-encode the `searcbar.value` parameter (use `encodeURIComponent` to fix it) - otherwise any non-alphanumeric chars will break your querystring and cause the HTTP 400. – Dai Jun 16 '23 at 03:05
  • 2
    Not related but you probably want to call `getWeather()` instead of `fetch(apiURL)` in the event listener. – Ricky Mo Jun 16 '23 at 03:06
  • Do not post anything like `API_KEY`. I've made API key hidden – Agrim Singh Jun 16 '23 at 03:07
  • 2
    Instead of using a simple string template, you can [build URL query with URLSearchParams](https://stackoverflow.com/questions/111529/how-to-create-query-parameters-in-javascript) to ensure correct encoding. – Ricky Mo Jun 16 '23 at 03:08
  • sorry i thought i left the api key out didnt meant to post that – Zavier walton Jun 16 '23 at 03:11
  • 6
    @AgrimSingh you know the edit history is visible to everyone, right? Zavier, I suggest you request a new key ASAP – Phil Jun 16 '23 at 03:11
  • 2
    You're never re-evaluating `apiURL` so the query string value will **always** be the initial value which is probably empty – Phil Jun 16 '23 at 03:13
  • 2
    thanks to the person who gave me advice on edit history key is deleted – Zavier walton Jun 16 '23 at 03:14
  • 2
    Instead of concatenating query parameters manually, please use the [`URL` API](//developer.mozilla.org/en/docs/Web/API/URL) and its `searchParams` property, which [_correctly encodes_ parameters](/a/44160941/4642212): `const url = new URL("https://api.openweathermap.org/data/2.5/weather?units=metric"); url.searchParams.set("q", searchbar.value); url.searchParams.set("appid", API_KEY); fetch(url);`. – Sebastian Simon Jun 16 '23 at 03:14
  • The key is not yet deleted, it is still in the post history. Please read [What should I do if a user posts sensitive information as part of a question or answer?](https://meta.stackexchange.com/questions/132117/what-should-i-do-if-a-user-posts-sensitive-information-as-part-of-a-question-or) — you should flag a moderator to expunge the key, after you have deleted it. It would probably also be good to invalidate the key and make a new one just in case, if you can. – Amadan Jun 16 '23 at 03:36

2 Answers2

1

Aggregating the comments, you should make the following changes:

  • re-evaluate the url everytime
  • use URL.searchParams
  • call getWeather() in submit event listener
document.querySelector('form').addEventListener('submit', (e) => {
  e.preventDefault();
  getWeather();
});

async function getWeather() { 
  const apiURL = new URL("https://api.openweathermap.org/data/2.5/weather");
  apiURL.searchParams.set("q",searchbar.value);
  apiURL.searchParams.set("units","metric");
  apiURL.searchParams.set("appid",API_KEY);
  const response = await fetch(apiURL.toString());
  const data = await response.json();
  console.log(data);
}
Ricky Mo
  • 6,285
  • 1
  • 14
  • 30
0
  1. The apiURL variable is moved inside the event listener, so it takes the current value of the #search-bar input when the form is submitted.

  2. Call getWeather function when the form is submitted.

  3. Use try-catch to handle any potential errors during the fetch operation.

const searchbar = document.querySelector('#search-bar');
const API_KEY = '<MY_API_KEY>';

document.querySelector('form').addEventListener('submit', (e) => {
  e.preventDefault();
  
  const apiURL = `https://api.openweathermap.org/data/2.5/weather?q=${searchbar.value}&units=metric&appid=${API_KEY}`;
  
  getWeather(apiURL);
});

async function getWeather(apiURL) {
  try {
    const response = await fetch(apiURL);
    const data = await response.json();
    console.log(data);
    
  } catch (error) {
    console.error('Error fetching weather data:', error);
  }
}
001
  • 2,019
  • 4
  • 22