I'm currently messing around with a couple game API's, I've setup a simple form to send a get request with query's to an API route that talks to the game server.
Currently it works great however if I try to map through the response after the form is submitted, I get an error that the map is not a function TypeError: stats.data.data.stats.all.map is not a function
Screenshot of issue
I've put the code for the component below, Any help is greatly appreciated.
import React from "react";
import axios from "axios";
import { VStack, Container, FormControl, FormLabel , Input, Button, Select, HStack } from "@chakra-ui/react";
const Index = () => {
const [data, setData] = React.useState([]);
const [name, setName] = React.useState("");
const [accountType, setAccountType] = React.useState("");
const [timeWindow, setTimeWindow] = React.useState("");
const [image, setImage] = React.useState("");
const [stats, setStats] = React.useState(null)
const [err, setErr] = React.useState(null)
const getuserData = async () => {
axios.get(`/api/getStats?name=${name}&accountType=${accountType}&timeWindow=${timeWindow}&image=${image}`, {
headers: {
Accept: "application/json",
},
})
.then((response) => {
setStats(response.data)
}
)
.then((response) => {
console.log('console log of prop', stats)
console.log('client side log', response.data);
console.log('client side log data.data', response.data.data);
console.log('client side repsonse log', response)
})
.catch((err) => {
setErr(err.message)
});
};
const handleSubmit = (e) => {
e.preventDefault();
getuserData();
};
console.log(stats)
return (
<React.Fragment>
<form onSubmit={handleSubmit}>
<FormControl>
<HStack>
<FormLabel >Enter Account Name: </FormLabel>
<Input
type="text"
name="name"
required
value={name}
placeholder="account name"
onChange={(e) => setName(e.target.value)}
/>
<FormLabel >Account Type: </FormLabel>
<Select
required
placeholder='Select Account Type'
onChange={(e) => setAccountType(e.target.value)}
>
<option value='epic'>PC</option>
<option value='psn'>Playstation</option>
<option value='xbl'>Xbox</option>
</Select>
<FormLabel >Time Played: </FormLabel>
<Select
required
placeholder='Select Window of Time Played'
onChange={(e) => setTimeWindow(e.target.value)}
>
<option value='season'>season</option>
<option value='lifetime'>lifetime</option>
</Select>
<FormLabel>Select Platform</FormLabel>
<Select
required
placeholder='Select The Platform You Play On!'
onChange={(e) => setImage(e.target.value)}
>
<option value='all'>All</option>
<option value='keyboardMouse '>Keyboard & Mouse</option>
<option value='gamepad'>Controller</option>
<option value='touch'>Mobile</option>
<option value='none'>None</option>
</Select>
</HStack>
</FormControl>
<Button type="submit" colorScheme="green" m="2">Search</Button>
</form>
{console.log('after form', stats)}
{console.log('status', stats && stats.data.status)}
{console.log('stats solo', stats && stats.data.data.stats.all.solo)}
<VStack>
<Container>
<img width="1000" height="1000" src={stats?.data.data.image} />
{/* {stats && stats.data.status.includes(200) ? (
<img width="1000" height="1000" src={stats?.data.data.image} />
) : (
<div>Error. Check your details are correct!</div>
)
} */}
{stats && stats.data.data.stats.all.map((stat =>
<code>{stat.solo.kills}</code>
))}
</Container>
</VStack>
</React.Fragment>
);
};
export default Index;
Raw json from debugger
// I did have to comment out the map in order for the response to comeback it. Not sure if that could also be
{
"data": {
"data": {
"status": 200,
"data": {
"account": {
"id": "9a8cc59adfff4f61902a11141b8c1d0e",
"name": "notCarried"
},
"battlePass": {
"level": 23,
"progress": 68
},
"image": "https://cdn.fortnite-api.com/stats/v2/d5875d6387983eaec7cc6fbfac706c1b0eb0527f.png",
"stats": {
"all": {
"overall": {
"score": 143447,
"scorePerMin": 10.995,
"scorePerMatch": 26.153,
"wins": 175,
"top3": 57,
"top5": 104,
"top6": 98,
"top10": 623,
"top12": 253,
"top25": 1163,
"kills": 8291,
"killsPerMin": 0.635,
"killsPerMatch": 1.512,
"deaths": 5310,
"kd": 1.561,
"matches": 5485,
"winRate": 3.191,
"minutesPlayed": 13047,
"playersOutlived": 32795,
"lastModified": "2022-04-12T11:44:46Z"
},
"solo": {
"score": 52697,
"scorePerMin": 22.932,
"scorePerMatch": 16.545,
"wins": 115,
"top10": 623,
"top25": 1163,
"kills": 5067,
"killsPerMin": 2.205,
"killsPerMatch": 1.591,
"deaths": 3070,
"kd": 1.65,
"matches": 3185,
"winRate": 3.611,
"minutesPlayed": 2298,
"playersOutlived": 19072,
"lastModified": "2022-04-10T13:52:22Z"
},
"duo": {
"score": 22598,
"scorePerMin": 23.787,
"scorePerMatch": 25.249,
"wins": 22,
"top5": 104,
"top12": 253,
"kills": 1179,
"killsPerMin": 1.241,
"killsPerMatch": 1.317,
"deaths": 873,
"kd": 1.351,
"matches": 895,
"winRate": 2.458,
"minutesPlayed": 950,
"playersOutlived": 6608,
"lastModified": "2022-04-12T11:44:46Z"
},
"trio": null,
"squad": {
"score": 10224,
"scorePerMin": 22.226,
"scorePerMatch": 14.904,
"wins": 10,
"top3": 57,
"top6": 98,
"kills": 700,
"killsPerMin": 1.522,
"killsPerMatch": 1.02,
"deaths": 676,
"kd": 1.036,
"matches": 686,
"winRate": 1.458,
"minutesPlayed": 460,
"playersOutlived": 3203,
"lastModified": "2021-07-31T15:31:26Z"
},
"ltm": {
"score": 63786,
"scorePerMin": 6.637,
"scorePerMatch": 85.275,
"wins": 28,
"kills": 1404,
"killsPerMin": 0.146,
"killsPerMatch": 1.877,
"deaths": 720,
"kd": 1.95,
"matches": 748,
"winRate": 3.743,
"minutesPlayed": 9611,
"playersOutlived": 5667,
"lastModified": "2021-07-31T15:31:26Z"
}
},
"keyboardMouse": {
"overall": {
"score": 125068,
"scorePerMin": 12.034,
"scorePerMatch": 163.061,
"wins": 8,
"top3": 3,
"top5": 18,
"top6": 9,
"top10": 47,
"top12": 39,
"top25": 111,
"kills": 924,
"killsPerMin": 0.089,
"killsPerMatch": 1.205,
"deaths": 759,
"kd": 1.217,
"matches": 767,
"winRate": 1.043,
"minutesPlayed": 10393,
"playersOutlived": 30539,
"lastModified": "2022-04-12T11:44:46Z"
},
"solo": {
"score": 48884,
"scorePerMin": 22.939,
"scorePerMatch": 132.119,
"wins": 3,
"top10": 47,
"top25": 111,
"kills": 274,
"killsPerMin": 0.129,
"killsPerMatch": 0.741,
"deaths": 367,
"kd": 0.747,
"matches": 370,
"winRate": 0.811,
"minutesPlayed": 2131,
"playersOutlived": 17621,
"lastModified": "2022-04-10T13:52:22Z"
},
"duo": {
"score": 21964,
"scorePerMin": 23.848,
"scorePerMatch": 184.571,
"wins": 4,
"top5": 18,
"top12": 39,
"kills": 173,
"killsPerMin": 0.188,
"killsPerMatch": 1.454,
"deaths": 115,
"kd": 1.504,
"matches": 119,
"winRate": 3.361,
"minutesPlayed": 921,
"playersOutlived": 6349,
"lastModified": "2022-04-12T11:44:46Z"
},
"trio": null,
"squad": {
"score": 9973,
"scorePerMin": 22.361,
"scorePerMatch": 169.034,
"wins": 0,
"top3": 3,
"top6": 9,
"kills": 84,
"killsPerMin": 0.188,
"killsPerMatch": 1.424,
"deaths": 59,
"kd": 1.424,
"matches": 59,
"winRate": 0,
"minutesPlayed": 446,
"playersOutlived": 3092,
"lastModified": "2021-07-31T15:31:26Z"
},
"ltm": {
"score": 50105,
"scorePerMin": 6.991,
"scorePerMatch": 202.036,
"wins": 1,
"kills": 452,
"killsPerMin": 0.063,
"killsPerMatch": 1.823,
"deaths": 247,
"kd": 1.83,
"matches": 248,
"winRate": 0.403,
"minutesPlayed": 7167,
"playersOutlived": 5232,
"lastModified": "2021-07-31T15:31:26Z"
}
},
"gamepad": {
"overall": {
"score": 18379,
"scorePerMin": 6.925,
"scorePerMatch": 3.896,
"wins": 167,
"top3": 54,
"top5": 86,
"top6": 89,
"top10": 576,
"top12": 214,
"top25": 1052,
"kills": 7367,
"killsPerMin": 2.776,
"killsPerMatch": 1.561,
"deaths": 4551,
"kd": 1.619,
"matches": 4718,
"winRate": 3.54,
"minutesPlayed": 2654,
"playersOutlived": 2256,
"lastModified": "2019-10-17T04:40:24Z"
},
"solo": {
"score": 3813,
"scorePerMin": 22.832,
"scorePerMatch": 1.355,
"wins": 112,
"top10": 576,
"top25": 1052,
"kills": 4793,
"killsPerMin": 28.701,
"killsPerMatch": 1.703,
"deaths": 2703,
"kd": 1.773,
"matches": 2815,
"winRate": 3.979,
"minutesPlayed": 167,
"playersOutlived": 1451,
"lastModified": "2019-10-17T04:40:24Z"
},
"duo": {
"score": 634,
"scorePerMin": 21.862,
"scorePerMatch": 0.817,
"wins": 18,
"top5": 86,
"top12": 214,
"kills": 1006,
"killsPerMin": 34.69,
"killsPerMatch": 1.296,
"deaths": 758,
"kd": 1.327,
"matches": 776,
"winRate": 2.32,
"minutesPlayed": 29,
"playersOutlived": 259,
"lastModified": "2019-01-12T02:30:20Z"
},
"trio": null,
"squad": {
"score": 251,
"scorePerMin": 17.929,
"scorePerMatch": 0.4,
"wins": 10,
"top3": 54,
"top6": 89,
"kills": 616,
"killsPerMin": 44,
"killsPerMatch": 0.982,
"deaths": 617,
"kd": 0.998,
"matches": 627,
"winRate": 1.595,
"minutesPlayed": 14,
"playersOutlived": 111,
"lastModified": "2019-01-18T06:46:27Z"
},
"ltm": {
"score": 13681,
"scorePerMin": 5.598,
"scorePerMatch": 27.362,
"wins": 27,
"kills": 952,
"killsPerMin": 0.39,
"killsPerMatch": 1.904,
"deaths": 473,
"kd": 2.013,
"matches": 500,
"winRate": 5.4,
"minutesPlayed": 2444,
"playersOutlived": 435,
"lastModified": "2019-07-14T08:15:54Z"
}
},
"touch": null
}
}
}
},
"status": 200,
"statusText": "OK",
"headers": {
"connection": "keep-alive",
"content-encoding": "gzip",
"content-type": "application/json; charset=utf-8",
"date": "Tue, 12 Apr 2022 11:48:19 GMT",
"etag": "\"1270-feipp1fYiZBY8Zu4RV0p6SZKj8U\"",
"keep-alive": "timeout=5",
"transfer-encoding": "chunked",
"vary": "Accept-Encoding"
},
"config": {
"transitional": {
"silentJSONParsing": true,
"forcedJSONParsing": true,
"clarifyTimeoutError": false
},
"transformRequest": [
null
],
"transformResponse": [
null
],
"timeout": 0,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1,
"maxBodyLength": -1,
"headers": {
"Accept": "application/json"
},
"method": "get",
"url": "/api/getStats?name=notCarried&accountType=epic&timeWindow=lifetime&image=all"
},
"request": {}
}
CodePudding user response:
The reason you are getting the error is because you are trying to map an Array, but the result you are getting is an Object.
try to wrap the result you are tryin to map inside Object.values()
;
let result = Object.values(response.data);
setStats(result);
Also, it would be better to get the exact data like this:
let result = Object.values(response.data.data.data.stats.all);
setStats(result);
so your code will be much cleaner as a result:
{stats && stats.map((stat =>
<code>{stat.solo.kills}</code>
))}
CodePudding user response:
.then((response) => {
debugger; // <- watch here what recieves in response data
setStats(response.data)
}