65

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?

1

8 Answers 8

91

.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();

Sign up to request clarification or add additional context in comments.

6 Comments

Thank you so much, .then(data => obj = data) was the missing part, now it is working.
Hey Yuri, could you kindly explain why this piece of code breaks if the 3rd then is not an anonymous function?
@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.
Thanks for replying @yuriy636, as I was writing the fiddle I figured it out (of course). Appreciate the follow up though, cheers 🍻 .
@Vayl .then takes in only anonymous functions. Even the arrow functions "res => res.json()" and "data => obj = data)" are anonymous functions.
|
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

{
    statusCode: 200,
    quote: {
        _id: '5db17aaeb69dc744b4e72b82',
        quoteText: 'I can take more punishment than anyone in the business.',
        quoteAuthor: 'Ric Flair',
        quoteGenre: 'business',
        __v: 0
    }
}

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

2 Comments

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 :-).
I made a mistake. It can only access function. We can define a var exam outside of the function. Excuse me for the mistake.
11

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)
}

Comments

4

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));

2 Comments

Adding a bit of explanation to what's actually happening here would be helpful to readers.
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 :)
3

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)
  

Comments

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.'

1 Comment

@Mienislav Just tried it again. It works.
-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()

Comments

-1

You can kinda do it a hacky sort of way with storage...

(async function foo() { 
  const res = await fetch('https://jsonplaceholder.typicode.com/posts/1');
  let obj = await res.json();
  let str = JSON.stringify(obj);
  localStorage.setItem("mydata", str);
  return obj;
})();

let myVar =  localStorage.getItem("mydata");
let v = JSON.parse(myVar);
console.log("Global: " + v.title);

3 Comments

This does not work, it will log undefined (at least the first time it's executed)
@Bergi this works for me.. here is a codepen of it working? codepen.io/TikiHead/pen/xbVXYar
It does not. Clear your storage, and make sure the codepen does not execute multiple times.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.