296
@job_hop_jules ·

My fetch returns a Promise instead of the data even with async await Debug Help

I have const data = await getUser() inside an async function and logging data gives me a Promise object instead of the user. Inside getUser I do fetch(url).then(res => res.json()) and I am fairly sure the endpoint works because the network tab shows a 200 with JSON. Where is the extra promise coming from?

8 answers Share
Report

Answering anonymously — a moderator will review it first.

  • @venv_val · 4mo ago · 3 replies

    Almost certainly a missing return inside getUser. If you wrote

    async function getUser() {
      fetch(url).then(res => res.json())
    }
    

    then the function returns undefined immediately and the fetch chain runs off into the void. Add the return, or better, rewrite it consistently:

    async function getUser() {
      const res = await fetch(url)
      return res.json()
    }
    

    The other classic cause is calling it without awaiting somewhere further up, for instance in a .map() where each callback returns a promise and you get an array of promises. Promise.all fixes that one.

    418
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @job_hop_jules · 4mo ago

      It was the missing return. Two hours. I am going to go lie down.

      132
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
    • @lubed_linears · 4mo ago

      The compensation is that you will spot it in five seconds forever afterwards. Missing return in an arrow function with braces is the single most common version of this.

      87
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
  • @eleven_tabs · 4mo ago

    Rule that saves a lot of pain: pick await or .then per function and do not mix them. Mixed style is where the stray promises hide, because you stop being able to see at a glance which values are resolved.

    214
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
  • @threat_modeler_j · 4mo ago · 3 replies

    Separately, while you are in there: fetch does not throw on a 404 or a 500, it only rejects on network failure. So check res.ok and throw yourself, otherwise you will eventually call .json() on an error page and get a confusing parse error instead of a useful message.

    268
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @job_hop_jules · 4mo ago

      Did not know that at all. Adding the check now.

      61
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
    • @vacuum_analyze · 4mo ago

      It surprises everyone once. The reasoning is that the request itself succeeded, the server just told you no.

      74
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
  • @backfill_bram · 4mo ago

    Quick diagnostic for next time: console.log(typeof data, data) and if you see the word Promise, the question is always which link in the chain forgot to hand the value back. Walk the chain outward one function at a time rather than staring at the call site.

    139
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report