Hazzamataza
Hazzamataza

Reputation: 993

Extracting JSON from Fetch API

I realise very similar questions have been answered before, but I'm still finding it very confusing as to how this works...

From my understanding promises are used to deal with asyc requests - these promises essentially send back the state or a "promise" that at some point later a JSON body (or other object) will be delivered.

What I'm trying to understand is how I properly handle these requests so that the function doesn't return until the JSON body is ready to be parsed.

Below I'm trying to simply extract the key "result" (which returns a string "result") and parse it to another variable that can be stored and then later used somewhere else in my code. Unfortunately, my code always returns a [Object Promise], rather than the extracted JSON. I believe this is because response.json is also a promise... however, I don't understand how I get out of the "chain of promises" and return a value that I can actually do something with.

Thanks for any advice,

async function name() {
    const response = await fetch('https://xxxxx.herokuapp.com/timespent', {});
    const json = await response.json();

    return json.result;
}

let varr = name();
console.log(varr)

Upvotes: 3

Views: 2527

Answers (5)

z0gSh1u
z0gSh1u

Reputation: 507

It is correct that you await fetch and .json since they are async.

async function name() {
  const response = await fetch('http://blah.com/api', {});
  const json = await response.json();
  return json.result;
}

However, async and Promises inside function name make it async too. So the return value of name is a Promise that you should await it, or .then it, like:

// Old style .then
name().then(result => console.log(result))

// Modern style await
async function main() {
  const result = await name()
  console.log(result)
}

Upvotes: 0

hhelsinki
hhelsinki

Reputation: 84

I'm actually looking for the answer(same as yours), so I found this way.

I. ASK/REQUEST for data

 async function fetchMyJson() {
 const response = await fetch('https://1stAPI.devdeveloper1.repl.co/fiveD');
 const myData = await response.json();
 return myData;
 }

II.GET Extract data

fetchMyJson().then(myData => {
let myData_output = myData.USD[0].rate; // fetched or Get OUTPUT data
console.log(myData_output);
document.body.innerHTML = `<div>${myData_output}</div>`; //make sure you add ${} for output
});

async function fetchMyJson() {
  const response = await fetch('https://1stAPI.devdeveloper1.repl.co/fiveD');
  const myData = await response.json();
  return myData;
}
//GET Extract data
fetchMyJson().then(myData => {
  let myData_output = myData.USD[0].rate; // fetched or Get OUTPUT data
  console.log(myData_output);
  document.body.innerHTML = `<div>${myData_output}</div>`; //make sure you add ${} for output
});

Upvotes: 0

jujule
jujule

Reputation: 11521

In your example code, name function is declared async, so it returns a promise.

Inside that function body, you correctly handle async calls like fetch or the JSON transformation.

What you need now is either use await to wait for the function to "resolve", or use the "older" then/catch promises methods. Note that you cannot always use await outside an async function so you may need to wrap it.

Example :

async function name() {
  const response = await fetch('https://mautargets.herokuapp.com/timespent', {});
  const json = await response.json();
  return json.result;
}

// using promise.then
name().then(result => console.log(result));

// wrapping await
(async function test() {
  try{
    console.log(await name());
  }catch(error) {
    // error goes here if promise got rejected
  }
})()

Upvotes: 1

Dyllan M
Dyllan M

Reputation: 301

You could have a callback in the function declaration, and use '.then(...)' and call it when the promise has been resolved:

async function name(cb) {
    const response = await 
    fetch('https://mautargets.herokuapp.com/timespent', {});
    const json = response.json();
    json.then(x => cb(x))
}
    
name(console.log)

This is because you're using an Async function, which will return a promise.

Or if you would like the method to return, you could either call it in another Asynchronous context and utilize await again:

// Assume no callback: code just as you had it.
async function wrapper() {
    console.log(await name())
}

Or you could do name().then(...) as specified before:

// Assume no callback: code just as you had it.
name().then(console.log)

Hope this helps!

Upvotes: 0

Ashish
Ashish

Reputation: 4330

Since your function is async it always return a promise. You need to use await for result.

read more about async here

async function name() {
  const response = await fetch('https://mautargets.herokuapp.com/timespent', {});
  const json = await response.json();
  return json.result;
    }

async function result(){
  //await can only be called from inside of async function. So we need async function for await name()
  
  let varr = await name();
  console.log(varr)  // Success
}

result()

Upvotes: 3

Related Questions