0

I have the following code:

 getWeather = e => {
    e.preventDefault();
    const api_call = fetch(
      `http://api.openweathermap.org/data/2.5/weather?q=London,uk&appid=${API_KEY}`
    );
    const data = api_call.json();
    console.log(data);
  };

But I keep getting .json() is not a function. Not sure why I am getting that.

vishalkohli
  • 87
  • 1
  • 2
  • 9
  • 1
    The `fetch` function returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). The Promise object does not have a `json()` function defined. – willman Mar 24 '20 at 20:51

4 Answers4

1

That's because you didn't wait for the request to end.

Try this instead:

const api_call = fetch(
  `http://api.openweathermap.org/data/2.5/weather?q=London,uk&appid=${API_KEY}`
).then(res => res.json()).then(console.log);
Guerric P
  • 30,447
  • 6
  • 48
  • 86
  • Thank you. But I thought it was synchronous. Is it not? – vishalkohli Mar 24 '20 at 20:48
  • @vishalkohli no fetch is async – messerbill Mar 24 '20 at 20:49
  • No @vishalkohli it's not. `XMLHttpRequest` still allows to make synchronous requests but it's considered as a bad practice (and display a warning in the console) since synchronous operations block the UI while they operate. – Guerric P Mar 24 '20 at 20:50
  • Thank you for your response. I ll learn Javascript going forward. Also, where is the response getting stored? How can I store the response in a variable lets say called data? – vishalkohli Mar 24 '20 at 20:51
  • You have to extract it with a callback, let's assume you declared a variable named `data` outside of the `fetch` you'll need something like `.then(json => data = json)`. Also if you're interested in a more "synchronous like" syntax you can use the `async`/`await` syntax but keep in mind that it's just syntaxic sugar, it doesn't bring any feature, just beautifies the code. – Guerric P Mar 24 '20 at 20:54
  • this is some good stuff. Last qs, why isnt the data coming from generic json ? – vishalkohli Mar 24 '20 at 20:58
0

Fetch returns a promise, so in your case you would want to use async/await:

getWeather = async e => {
    e.preventDefault();
    const api_call = await fetch(`http://api.openweathermap.org/data/2.5/weather?q=London,uk&appid=${API_KEY}`);
    const data = api_call.json();
    console.log(data);
};

Or you could use .then() and .catch() blocks:

getWeather = e => {
    e.preventDefault();

    fetch(`http://api.openweathermap.org/data/2.5/weather?q=London,uk&appid=${API_KEY}`)
    .then(res => res.json())
    .then(res => {
        console.log(res)
    })
    .catch(err => console.log(err))
};
sundaycode
  • 448
  • 2
  • 9
0

Use await on fetch (returns a Promise)

getWeather = async e => {
    e.preventDefault();
    const api_call = await  fetch(`http://api.openweathermap.org/data/2.5/weather?q=London,uk&appid=${API_KEY}`);
    const data = api_call.json();
    console.log(data);
  };
Ado
  • 637
  • 1
  • 6
  • 17
0

Put await before fetch and make the function async

 getWeather = async e => {
e.preventDefault();
const api_call = await fetch(
  `http://api.openweathermap.org/data/2.5/weather?q=London,uk&appid=${API_KEY}`
);
const data = api_call.json();
console.log(data);

};