57

Please, how can I save output of fetch to a variable - to be able to work with it as with an object?

Here is the code:

var obj;
fetch("url", {
  method: "POST",
  body: JSON.stringify({
    "filterParameters": {
      "id": 12345678
    }
  }),
  headers: {"content-type": "application/json"},
  //credentials: 'include'
})
.then(res => res.json())
.then(console.log)

The final console.log will show an object. But when I tried to save it to variable .then(res => obj = res.json()) than the console.log(obj) will not hold the Object, but the Promise.

Console

Any idea please, how to turn it into an Object saved in the variable?

Vlasta Po
  • 821
  • 1
  • 10
  • 12

7 Answers7

81

.json() is an async method (it returns a Promise itself), so you have to assign the parsed value in the next .then()

var obj;

fetch('https://jsonplaceholder.typicode.com/posts/1')
  .then(res => res.json())
  .then(data => {
    obj = data;
   })
  .then(() => {
    console.log(obj);
   });

Modern async/await equivalent

You have to await the .json() method.

async function foo() {
  let obj;

  const res = await fetch('https://jsonplaceholder.typicode.com/posts/1')

  obj = await res.json();

  console.log(obj)
}

foo();
yuriy636
  • 11,171
  • 5
  • 37
  • 42
  • 3
    Thank you so much, `.then(data => obj = data)` was the missing part, now it is working. – Vlasta Po Jul 10 '17 at 18:02
  • Hey Yuri, could you kindly explain why this piece of code breaks if the 3rd then is not an anonymous function? – Vayl Oct 09 '21 at 17:46
  • 1
    @Vayl Could you create a reproduction in jsfiddle or something? I just tried extracting the code to a function and it still works as expected. – yuriy636 Oct 09 '21 at 18:43
  • Thanks for replying @yuriy636, as I was writing the fiddle I figured it out (of course). Appreciate the follow up though, cheers . – Vayl Oct 10 '21 at 06:15
  • @Vayl .then takes in only anonymous functions. Even the arrow functions "res => res.json()" and "data => obj = data)" are anonymous functions. – chess_madridista Jun 25 '22 at 12:26
29

Instead of storing in a variable, create a function that will return data, and then store it in a variable. So It can accessible in your whole file.

async function fetchExam(id) {
        try {
            const response = await fetch(`/api/exams/${id}`, {
                method: 'GET',
                credentials: 'same-origin'
            });
            const exam = await response.json();
            return exam;
        } catch (error) {
            console.error(error);
        }
    }

Then call that function to get data

async function renderExam(id) {
        const exam = await fetchExam(id);
        console.log(exam);
}

Update

With the current version of Node.js v14.3.0 support Top-Level async-await

import axios from 'axios';

const response = await axios('https://quote-garden.herokuapp.com/api/v3/quotes/random');
console.log(response.data);

Running this file using node --harmony-top-level-await top-level-async-await.js

Output

output

More details: https://medium.com/@pprathameshmore/top-level-await-support-in-node-js-v14-3-0-8af4f4a4d478

Prathamesh More
  • 1,470
  • 2
  • 18
  • 32
  • 2
    How is this variable 'exam' accessible in the whole file? It seems te be stuck in the function renderExam (when I try to 'return' it is pending like in the original problem. Please enlighten me :-). – Ronald Vonk Jun 28 '20 at 11:37
  • I made a mistake. It can only access function. We can define a var exam outside of the function. Excuse me for the mistake. – Prathamesh More Jun 28 '20 at 11:40
9

You can do like this. First fetch the data and create a function to do something with the data.

And then pass the result to that function and access it anywhere.

fetch('https://pokeapi.co/api/v2/pokemon/ditto')
    .then(jsonData => jsonData.json())
    .then(data => printIt(data))

let printIt = (data) => {
    console.info(typeof data)
}
crg
  • 4,284
  • 2
  • 29
  • 57
Rasla
  • 91
  • 1
  • 4
4

let data = [];

async function getRandomUser(){
  // gets the response from the api and put it inside a constant
  const response = await fetch('https://randomuser.me/api');
  //the response have to be converted to json type file, so it can be used
  const data = await response.json();
  //the addData adds the object "data" to an array
  addData(data)
}

function addData(object) {
  // the push method add a new item to an array
  // here it will be adding the object from the function getRandomUser each time it is called
  data.push(object);
  //the fetched data is available only on this scope
  console.log("This is the value of date inside the function addData:")
  console.log(data)
}

//Calls the function that fetches the data
getRandomUser()

  console.log("This is the value of data outside the scope")
  console.log(data)
  
Sam
  • 723
  • 5
  • 18
3

A simple and handy solution is :

function myFunc(success) {
//do what you want HERE.

console.log(success)

}

fetch('https://reqres.in/api/users?page=2')
    .then(data => data.json())
    .then(success => myFunc(success));
amir mohseni
  • 274
  • 2
  • 6
  • 1
    Adding a bit of explanation to what's actually happening here would be helpful to readers. – Zenahr Jan 23 '23 at 08:52
  • yes, of course BTW i think its clear, read Question, then see answer :) pulling out data after fetch and push it to a function to use it in that function :) – amir mohseni Jan 25 '23 at 06:28
0

I've done this before. It's quite simple actually. Here is how I did it with an API I sometimes use:

x = await fetch("https://api.quotable.io/random").then((res)=>res.json()).then((json)=>json.content)
console.log(x) // Returns 'The world cares very little about what a man or woman knows; it is what a man or woman is able to do that counts.'

Alternatively, you can also do:

x = fetch("https://api.quotable.io/random").then((res)=>res.json()).then((json)=>json.content)
console.log(await x) // Returns 'The world cares very little about what a man or woman knows; it is what a man or woman is able to do that counts.'
Joe
  • 415
  • 1
  • 5
  • 15
-1

Easiest approach is to use async/await method.

Simply copy & paste the following code in your chrome dev console to see the magic:

async function githubUsers() {
            let response = await fetch('https://api.github.com/users')
            let users = await response.json()
            console.log(users)
    }

githubUsers()
Shoaib Khalil
  • 1,874
  • 17
  • 10