Hello I'm fairly new to react/js and I am trying to sort some data that I am fetching from the an api using Apollo then render the data into a grid. When I try to use the sort() function I get and error in the console "TypeError: Attempting to change configurable attribute of unconfigurable property.". Can anyone help explain what I'm doing wrong? Many thanks
This is the code I've tried. It works without the data.ammo.sort method.
I was expecting the data to be rendered in order sorted by damage
import { useQuery, gql } from '@apollo/client';
import AmmoBox from "./components/Ammo"
import {Grid} from "@chakra-ui/react"
export const GET_AMMO = gql
`{
ammo{
item {
id
name
shortName
}
damage
penetrationPower
caliber
}
}`
function App() {
const { loading, error, data } = useQuery(GET_AMMO);
if (loading) return 'Loading';
if (error) return 'Error';
console.log(data.ammo);
//sort data here before mapping to AmmoBox component*
data.ammo.sort((a, b) => a.damage - b.damage);
return (
<Grid templateColumns='repeat(5, 1fr)' gap={6}>
{data.ammo
.map((ammos) => (
<AmmoBox name={ammos.item.name} caliber={ammos.caliber} penetration={ammos.penetrationPower} damage={ammos.damage}/>))}
</Grid>
);
}
export default App;
Since the error says you can't change data.ammo
, spread the data to a new (shallow-copied) array sortedArray
and apply .sort()
method to this new array.
Check code below:
function App() {
const { loading, error, data } = useQuery(GET_AMMO);
if (loading) return 'Loading';
if (error) return 'Error';
console.log(data.ammo);
// Spread ammo data to a new shallow-copied array and use sort() function on the new array
const sortedArray = [...data.ammo].sort((a, b) => a.damage - b.damage);
return (
<Grid templateColumns='repeat(5, 1fr)' gap={6}>
{sortedArray
.map((ammos) => (
<AmmoBox name={ammos.item.name} caliber={ammos.caliber} penetration={ammos.penetrationPower} damage={ammos.damage}/>))}
</Grid>
);
}
Mozilla Docs - Array.prototype.sort() :
The sort() method returns a reference to the original array, so mutating the returned array will mutate the original array as well.
In case you want sort() to not mutate the original array, but return a shallow-copied array like other array methods (e.g. map()) do, you can do a shallow copy before calling sort(), using the spread syntax or Array.from().