1

This is my fetch function:

getAllCountries = async () => {
    try {
      const response = await fetch("https://restcountries.eu/rest/v2/all");
      const result = response.json();
      console.log(result);
      this.countriesList = result;
    } catch (error) {
      console.log(error);
    }
  };

In the console, it logs enter image description here

Why is there two promise logged in there, and how do I access the PromiseResult. I tried console.log(result[0]) but did not work

VLAZ
  • 26,331
  • 9
  • 49
  • 67
wyfy
  • 361
  • 1
  • 3
  • 8
  • Shouldn't you call `.then` after your promise so that the `await` stores the `.json()` result? e.g. `const result = await fetch('...').then(resp => resp.json());` – Mr. Polywhirl Sep 08 '20 at 13:11
  • @Mr.Polywhirl - No, it's almost never appropriate to call `.then` or `.catch` within an `async` function. Just use `await` a second time. (That said, your code would *work*.) – T.J. Crowder Sep 08 '20 at 13:12

1 Answers1

6

json() also returns a promise, so:

  getAllCountries = async () => {
    try {
      const response = await fetch("https://restcountries.eu/rest/v2/all");
      const result = await response.json();
//                   ^^^^^−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− add
      console.log(result);
      this.countriesList = result;
    } catch (error) {
      console.log(error);
    }
  };

Side note: That code is falling prey to the fetch API footgun: fetch only rejects its promise on network error, not HTTP error. You have to check for those yourself, e.g.:

  getAllCountries = async () => {
    try {
      const response = await fetch("https://restcountries.eu/rest/v2/all");
      if (!response.ok) {                                   // ***
        throw new Error("HTTP error " + response.status);   // ***
      }                                                     // ***
      const result = await response.json();
      console.log(result);
      this.countriesList = result;
    } catch (error) {
      console.log(error);
    }
  };
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Why check for `!response.ok` when you can have a `catch` clause in the `fetch` Promise? See: [_"Error handling with promises"_](https://javascript.info/promise-error-handling) – Mr. Polywhirl Sep 08 '20 at 13:13
  • @Mr.Polywhirl - I'm not sure what part of that link you're referring to. You saw the explanation above about the `fetch` footgun? Also: http://blog.niftysnippets.org/2018/06/common-fetch-errors.html If you blindly call `json` when the HTTP operation wasn't successful, most likely it'll fail because most likely the server didn't return JSON on error (it may, but that's not the usual case), and that failure will hide the actual failure: The HTTP problem. – T.J. Crowder Sep 08 '20 at 13:22
  • 1
    OK, so I think I understand what you are saying now. Avoid using typical Promise chaining inside of an `async` function, because (although they are equivalent) `async` is the successor to Promises and mixing them is rather pointless. I think the following article describes this effectively, [_"6 Reasons Why JavaScript Async/Await Blows Promises Away"_](https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9). I have seen the light. – Mr. Polywhirl Sep 08 '20 at 13:28
  • thank you for your answer, but how may I access the data in response object ? – wyfy Sep 08 '20 at 13:40
  • @wyfy - I don't understand the question. The above stores the data from the resonse in `this.countriesList`...? – T.J. Crowder Sep 08 '20 at 13:43
  • 1
    sorry for the confusion, I just add `await` to my `response.json()` and now I can access the data. Thanks a lot @T.J.Crowder – wyfy Sep 08 '20 at 13:49