fetch("https://jsonplaceholder.typicode.com/posts").then( (response) => { console.log(response.json()); //why the data not logged and promise is logged } ); but work if i writte let response = fetch("https://jsonplaceholder.typicode.com/posts") .then((response) => response.json()) .then((data) => console.log(data));
why the data is not logged and promise is logged in the first code?
Advertisement
Answer
This is only to demonstrate how you would get the data out of the promise (don’t do it this way):
fetch("https://jsonplaceholder.typicode.com/posts").then( (response) => { // response.json() returns a Promise which we can call // .then() on. response.json().then(console.log) } );
The second code is actually a shortened version of:
let response = fetch("https://jsonplaceholder.typicode.com/posts") .then((response) => { return response.json() }) // .then() refers to the promise returned by response.json() .then((data) => { return console.log(data) });
This is the correct way of chaining Promises.
As you can see, we return the Promise returned by response.json()
and then call .then()
on it.
The good thing about chaining Promises is that synchronous values (like numbers, strings etc.) get wrapped in a Promise so you can still call .then()
on it:
let dummy_promise = (new Promise(resolve => { resolve(1) })) dummy_promise.then(value => { console.log("im expecting 1", value) return 2; }) .then(value => { console.log("im expecting 2", value) return 3; }) .then(value => { console.log("im expecting 3", value) }) .then(value => { console.log("im expecting undefined because we haven't returned anything in the previous .then() block!", value) })
A little background information:
You cannot expect the result of a Promise to be available immediately.
This is why you use .then()
– it’s a way of saying “call this function when the value IS available”.
When you console.log(response.json())
you get the Promise object, but not it’s resolved value.
Note: Even if the Promise itself was resolved, response.json()
will continue to give you the Promise object itself.
You can still call .then()
on it and your function will be called with the resolved value.
I hope this small example shows what I mean:
// returns a Promise that gets resolved to "hello!" after // 100 ms (milliseconds) function something() { return new Promise((resolve) => { setTimeout(() => { resolve("hello!") }, 100) }) } // call something() and store the promise in promise_object let promise_object = something() console.log("Installing .then() handlers") // call console.log twice after promise is resolved // (means they will be called in about 100ms - when the promise is resolved) promise_object.then(console.log) promise_object.then(console.log) console.log("Installed .then() handlers") // wait for 1 second, then print promise_object setTimeout(() => { console.log("1 second has passed") // at this point the promise returned by something() surely must be // resolved console.log(promise_object) // Still prints Promise {} and not "hello!" - that's intended behavior // gets called without delay because promise is already resolved! promise_object.then(console.log) }, 1000)
Output: