I would like to print out data in my html from the link, but it always says "undefined" and I dont know, where is the problem. Can anyone help, please?
let url = 'https://ac7minh6n7s3rw4qfchrofbwai0amiko.lambda-url.eu-north-1.on.aws/';
fetch(url)
.then(res => res.json())
.then(out => console.log('JSON: ', out))
.then(out => document.write('JSON string: ', JSON.stringify(out)))
.catch(err => { throw err })
The value passed to the then callback is the return value of the previous link in the chain. If that value is a promise, it is resolved before then is called.
.then(out => console.log('JSON: ', out))
The return value of console.log is undefined so you are passing undefined into the function which tried to document.write the value.
You need to return the value you want to handle:
.then(out => {
console.log('JSON: ', out);
return out;
})
However since you aren't creating a new promise, there's really no need to use an extra then. You can just merge the two:
.then(out => {
console.log('JSON: ', out);
document.write('JSON string: ', JSON.stringify(out);
return out;
})
The reason it is undefined is because the return value of console.log() is undefined. Removing it allows out to be referenced:
let url = 'https://ac7minh6n7s3rw4qfchrofbwai0amiko.lambda-url.eu-north-1.on.aws/';
fetch(url)
.then(res => res.json())
.then(out => document.write('JSON string: ', JSON.stringify(out)))
.catch(err => { throw err });
Related
I thought I fully understood promises, but I'm stumped on this. I realize I should use async/await, but for this example I specifically want to only use .then().
When I do this:
const theJson = fetch(
`https://s3-us-west-2.amazonaws.com/s.cdpn.io/28963/quotes.json`
)
.then( quoteTypeResponse => quoteTypeResponse.json() )
.then( data => {
console.log(data)
return data
});
the console.log(data) in the last function prints the JSON as expected, but when I try to console.log(theJson), the returned value, it prints [object Promise].. Why is this?
I was able to get the data outside of the function using react's useState/useEffect but not with just a vanilla global variable. I'm not trying to solve anything, but just want to understand why this does not work.
export default function App() {
let globalVar;
const [theQuote, setTheQuote] = useState({});
useEffect(() => {
fetch(`https://s3-us-west-2.amazonaws.com/s.cdpn.io/28963/quotes.json`)
.then(quoteTypeResponse => quoteTypeResponse.json())
.then(quoteType =>
fetch(
'https://programming-quotes-api.herokuapp.com/quotes/' +
quoteType.type
)
)
.then(quoteResponse => {
return quoteResponse.json();
})
.then(quote => {
setTheQuote({ quote: quote.en, author: quote.author });
globalVar = quote.author;
});
}, []);
return (
<div id="app">
<h1>{theQuote.quote}</h1> // renders
<h2>{theQuote.author}</h2> // renders
<h3>globalVar: {globalVar}</h3> // undefined
</div>
);
}
Because your second .then() is inside the first then(), so theJson is a Promise<T>. The nice thing about Promise<T> is that you can move an inner .then() call up a level and it will still work:
Change it from this:
const theJson = fetch(
`https://s3-us-west-2.amazonaws.com/s.cdpn.io/28963/quotes.json`
)
.then( quoteTypeResponse => quoteTypeResponse.json().then( data => {
console.log(data)
return data
} )
);
To this:
const theJson = fetch(
`https://s3-us-west-2.amazonaws.com/s.cdpn.io/28963/quotes.json`
)
.then( quoteTypeResponse => quoteTypeResponse.json() )
.then( data => {
console.log(data)
return data
});
But ideally, use async function so you can have this considerably simpler code instead:
const resp = await fetch( `https://s3-us-west-2.amazonaws.com/s.cdpn.io/28963/quotes.json` );
const data = await resp.json();
console.log( data );
#pushkin left a good link explaining the differences between async/await and using .then(), but basically, the value returned by the then() is only available within that block.
Promises cheat sheet: https://levelup.gitconnected.com/async-await-vs-promises-4fe98d11038f
fetch(`https://s3-us-west-2.amazonaws.com/s.cdpn.io/28963/quotes.json`)
.then(quoteTypeResponse => quoteTypeResponse.json())
.then(quoteType =>
fetch(
'https://programming-quotes-api.herokuapp.com/quotes/' + quoteType.type
)
)
.then(quoteResponse => {
return quoteResponse.json();
})
.then(quote => {
console.log(`q:${util.inspect(quote)}`);
document.getElementById('app').innerHTML = quote.en;
});
Am trying to get value from nested json. but got 'undefined' error. when i display the same object in console, it works fine. I want to fetch particular field from nested json object.
here is the json output from api, i want to fetch userid, name and verified fields from below json
{
status: true,
user:
{
id: 11362
phone: "+918971557357"
name: "Sagar pawar"
email: null
bio: null
address: null
date_of_birth: null
token: "EMAWdBl3LDjl1X5veo6VvZBKfgQns5wTFXKWjIh9w4VKKXlclRo5ZBlWaJUBS5ImaVZANN9DlHSbFWquObaW1FIJLVGPqFLWKoPEzKLvZAJakhoTxg5TRTjVtLEVz9R9zAbocwF7dmRdI4GCAMlJdtKOEZAUuOcf6AZD"
image: ""
role: "user"
notification_cleared: {date: "2019-12-28 11:42:34.899503", timezone_type: 3, timezone: "UTC"}
deleted_by: null
blocked: 0
verified: 0
}
}
and this is the fetch function i tried.
fetch(url, options)
.then(res => res.json())
.then(body => console.log("Data Response", body))
.then(data => {
const jsonobj = data.user.id;
console.log("User ID:", jsonobj);
})
and this one i have tried.
const [responseUserId, setUserId] = useState(userId);
...
fetch(url, options)
.then(res => res.json())
.then(res =>
setUserId({ userId: res.user['id'] })
)
thanks in advance.
First and foremost. In your fetch function when you log data, in the second then you don't return any data, so in the third then your callback argument is undefined. After console.log("Data Response", body), you should add return body, so it get's passed down as data in your next then statement.
Second, your id is a string(or number, it doesn't matter). So your responseUserId will be a string. So when setting the state with useState you don't need to pass in an object, just pass the value. Like this : setUserId(res.user['id'])
Hope this helps!
i create a simple fetch request and setUserId just like you want and it works.
the problem is you use 3 then methods you only need 2.
in the third then data is undefind but in second you have what you need.
.then(res => res.json())
.then(body => console.log("Data Response", body))
.then(data => {
https://codesandbox.io/s/reverent-mestorf-o43s1
it is so simple i hope it help you
I will use your last example of a functional component with useState:
You initialize responseUserId with userId. Given the code you provided, that should fail to compile, because userId is not defined. Give it a value, like null, or 0 or an empty string.
If you return an object with only one property, you probably don't need the object data type. In my example data.userId and consequently responseUserId is of type Number.
import React, { useEffect, useState } from 'react';
export default function App() {
const [responseUserId, setResponseUserId] = useState(null);
useEffect(() => {
const url = 'https://jsonplaceholder.typicode.com/todos/1';
fetch(url)
.then(res => res.json())
.then(data => setResponseUserId(data.userId))
.catch(err => console.error(err));
}, []);
return responseUserId && <h3>{responseUserId}</h3>;
}
I have a mocked file mockedfile.html which I am redirecting to locally. My problem is that when I try to extract the HTML from the fetch response, the result does not look exactly like the mocked file. So this is what I do:
fetch('/some-url.html').then(response => {
if (response.redirected) { // this will be true locally
fetch(response.url) // which will then be /mockedfile.html
.then(res => res && res.text())
.then(text => text) // expect this text to be the same as the content inside mockedfile.html, but this is just partly the same
} else {
response && response.text().then(text => text);
}
}
})
What am I missing? Is there a more propper way to solve this?
To get the values outside of your fetch, you need the first .then() return something.
The extra .then() is unnecessary, because it just creates a new promise resolving to the same value.
fetch('/some-url.html')
.then(response => {
if (response.redirected) {
return fetch(response.url)
.then(res => res.text());
}
return response.text();
})
.then(console.log)
.catch(console.error)
You have to add ) to close brace opened at then(
fetch('/some-url.html').then(response => {
if (response.redirected) { // this will be true locally
fetch(response.url) // which will then be /mockedfile.html
.then(res => res && res.text())
.then(text => text) // expect this text to be the same as the content inside mockedfile.html, but this is just partly the same
} else {
response && response.text().then(text => text);
}
});
})
fetch(url).then(result => result.text()).then(yourText => ...);
I have 2 json's which I get on making 2 different API calls.
fetch(`veb/api/roleDetails/${id}`).then(response =>
response.json()
).then(responseJson => {
console.log('responseJson = ' + JSON.stringify(responseJson));
this.setState(() => {
return {
allRoleDetails: responseJson,
}
});
}
).catch(error => console.error('Error:', error))
2nd:
fetch(`/api/api/itemTypes`).then(response =>
response.json()
).then(responseJson => {
console.log('responseJson = ' + JSON.stringify(responseJson));
this.setState(() => {
return {
names: responseJson,
}
});
}
).catch(error => console.error('Error:', error))
in the 1st api call I get itemtypeid from which I have to make the 2nd api call to fetch the name of the typeid.Even if I get a combined json it will be fine
How to do that?Any help will be great.
Thanks
Promise.all is what you need. Basically, what it does is merging a collection of promises into one single promise, and return the resolved values one everything inside the collection done.
Promise.all([
fetch(`veb/api/roleDetails/${id}`).then(response => response.json()),
fetch(`/api/api/itemTypes`).then(response => response.json())
]).then(([allRoleDetails, names]) => {
// allRoleDetails is the resolve of your first promise
// names is the resolve of your second promise
}).catch(err => {
// catch error here
});
More details about Promise.all can be found here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
When I used SuperAgent I didn't have this problem, but I decided to use Window.fetch polifyl and I met this problem. I see all data was loaded, but it still shows error.
Could your help me identify this error please:
In render() I genereate a list of components based on an obtained list:
render() {
if (this.state.data.list) {
console.log("render: " + this.state.data.list);
var counter = 0;
const list = this.state.data.list.map((item) => {
....
The promise handlers in your screenshot won't work:
.then((json) => console.log('parsed json: ', json))
.then((json) => { this.setState({ data: json }); })
"Take the value from resolving this promise and pass it to console.log. Then, take console.log's return value (which is undefined) and pass it to this.setState."
fetch(url, {
headers: {
'Accept': 'application/json',
},
}).then((response) => response.json()
.catch(err => {
console.err(`'${err}' happened!`);
return {};
}))
.then((json) => {
console.log('parsed json: ', json);
this.setState({ data: json })
})
.catch((err) => { console.log('fetch request failed: ', err) }
)