Juanse Cora
Juanse Cora

Reputation: 935

Don't get expected data with fetch/async/await

Coming from Jquery $.get, I am trying to rewrite a function that gets data in a json. So far, this is what I do:

async function get_highlights(){
  const mirespuesta = await fetch("/api/v1/gethighlights/"+network_number)
  .then(response => {
      if (!response.ok) {
          throw new Error("HTTP error " + response.status);
      }
      return response.json();
  })
  .then(json => {
      console.log(json) // --> here, I get the correct dara
      return json;
  })
  .catch(function () {
      this.dataError = true;
  })
  return mirespuesta
} // but I don't get that data returned 

But I just get this when I call the fuction:

enter image description here

that has the values, but I can't get them returned or used on the main scope of my application.

What am I doing wrong?

Upvotes: 1

Views: 3928

Answers (3)

Rojo
Rojo

Reputation: 2869

Another way would be to use just await twice

try {
  const mirespuesta = await (await fetch("/api/v1/gethighlights/"+network_number)).json();
} catch {
  throw new Error(response.status);
}
return mirespuesta;

Upvotes: 1

Adam Jenkins
Adam Jenkins

Reputation: 55613

This is what your function should look like:

async function get_highlights() {
  const mirespuesta = await fetch("/api/v1/gethighlights/"+network_number);
  if (!mirespuesta.ok) {
      throw new Error("HTTP error " + mirespuesta.status);
  }
  return mirespuesta.json(); 
} 

But, most importantly this is how it should be used:

const mydata = await get_highlights();

An async function ALWAYS returns a promise, and your question probably becomes a dupe of this question

Upvotes: 4

T.J. Crowder
T.J. Crowder

Reputation: 1073968

The problem is that you never return the promise chain from your function. So your async function's return value is a promise fulfilled with undefined, just like a non-async function with no return returns undefined.

There's another issue with that code: If you're using an async function, generally it's best to use await rather than .then, .catch, etc. Also, don't catch rejection in the function; instead, let the caller handle it so it knows something went wrong.

So for instance:

async function get_highlights() {
    const response = await fetch("/api/v1/gethighlights/"+network_number);
    if (!response.ok) {
        throw new Error("HTTP error " + response.status);
    }
    return response.json();
}

But if you really want to handle errors inline:

async function get_highlights() {
    const response = await fetch("/api/v1/gethighlights/"+network_number);
    if (!response.ok) {
        throw new Error("HTTP error " + response.status);
    }
    try {
        return await response.json();
    } catch { // Note: ES2019 allows optional `catch` bindings 
        this.dataError = true;
    }
}

but again I don't recommend that, because the caller has to check to see whether they got data or undefined when the promise is fulfilled (or check dataError, I guess :-) ).

Side note: Note that in the first example, which doesn't have a try/catch, I did return response.json(); but in the second example, where the return is inside a try/catch, I did return await respohnse.json();. The reason is that when returning a promise at the top level of the function, there's no effective difference between return somePromise and return await somePromise, but that's not true if the code is in a control block like a try/catch. Having the await ensures that our catch block is executed if the promise is rejected. Not having it wouldn't ensure that.

Upvotes: 6

Related Questions