I have a helper function that uses FETCH to pull data from an API. I'm trying to set the response of the fetch request to my state using setState() but it keeps returning undefined. Here is my helper function: (I realize I'm exposing my keys on the front end but I will adjust if I ever deploy to production)
const authCode = {
async getAuthCode() {
const authCodeMatch = window.location.href.match(/code=([^&]*)/)[1];
await fetch(`https://id.twitch.tv/oauth2/token?client_id=${TWITCH_ID}&client_secret=${TWITCH_SECRET}&code=${authCodeMatch}&grant_type=authorization_code&redirect_uri=${TWITCH_CB}`, {
method: 'POST',
mode: 'cors',
'Access-Control-Allow-Origin':'*',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json'
}
})
.then(response =>
response.json()
)
.then(data => {
console.log(data.access_token);
fetch(`https://api.twitch.tv/helix/users?id=43691`, {
method: 'GET',
mode: 'cors',
'Access-Control-Allow-Origin':'*',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
'Client-ID': TWITCH_ID,
'Authorization': 'Bearer ' + data.access_token
}
})
.then(response => response.json())
.then(newdata => {
console.log(newdata);
if (!newdata.data) {
return [];
}
//console.log(newdata.data[0].view_count);
return newdata.data.map(views => ({
view_count: views.view_count
}))
})
})
}
Everything logs to the console fine so I'm pretty sure I'm mapping through the correct array to parse the data. In any case, here is the returned object in console as well as my component code. In my profile component it just pushes undefined to my state:
// Console response
data: Array(1)
0:
broadcaster_type: "partner"
description: ""
display_name: "Faker"
id: "43691"
login: "faker"
offline_image_url: "https://static-cdn.jtvnw.net/jtv_user_pictures/7d76e34d-3ee3-42c0-a46b-e320d37fcde6-channel_offline_image-1920x1080.jpeg"
profile_image_url: "https://static-cdn.jtvnw.net/jtv_user_pictures/b2eb8a23-d6ad-45aa-bd8e-062133b64452-profile_image-300x300.png"
type: ""
view_count: 81769581
__proto__: Object
length: 1
__proto__: Array(0)
Component
export default class Profile extends Component {
constructor(props) {
super(props);
this.state = {
viewData: []
}
this.handleNewPost = this.handleNewPost.bind(this);
}
handleNewPost () {
authCode.getAuthCode().then(viewcountResults => {
this.setState({viewData: viewcountResults})
})
}
render() {
return (
<div>
<Container>
<div className='mt-5'>
<Button color='success' size='lg' onClick={this.handleNewPost}>
Post Data
</Button>
</div>
<div>
{this.state.viewData.view_count}
</div>
</Container>
</div>
)
}
Thanks for any help!
Your function getAuthCode
isn't returning a Promise containing the data you're wanting to receive. Also, you can greatly clean up that code by using await
instead of a mixture of await
and callbacks.
const authCode = {
async getAuthCode() {
const authCodeMatch = window.location.href.match(/code=([^&]*)/)[1];
let response = await fetch(`https://id.twitch.tv/oauth2/token?client_id=${TWITCH_ID}&client_secret=${TWITCH_SECRET}&code=${authCodeMatch}&grant_type=authorization_code&redirect_uri=${TWITCH_CB}`, {
method: 'POST',
mode: 'cors',
'Access-Control-Allow-Origin':'*',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json'
}
});
const data = await response.json();
console.log(data.access_token);
response = await fetch(`https://api.twitch.tv/helix/users?id=43691`, {
method: 'GET',
mode: 'cors',
'Access-Control-Allow-Origin':'*',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
'Client-ID': TWITCH_ID,
'Authorization': 'Bearer ' + data.access_token
}
});
const newData = await response.json();
console.log(newdata);
if (!newdata.data) {
return [];
}
return newdata.data.map(views => ({
view_count: views.view_count
}));
}
}