Im trying to sort the data i'm getting from graphQL..please look at the print screen if you see any problems.
I wanna be able to click the "Size" table head and sort the table by diameter.
The error i'm getting is TypeError: Cannot assign to read only property '0' of object '[object Array]'
This is my query:
import React from 'react';
import { useQuery, gql } from '@apollo/client';
import { useState, useEffect } from 'react';
import { useHistory } from 'react-router-dom';
const ALL_PLANETS = gql`
query {
allPlanets {
planets {
id
name
gravity
diameter
population
}
}
}
`;
And the rest:
function PlanetList() {
const [sortTable, setSortTable] = useState('default');
const { loading, error, data } = useQuery(ALL_PLANETS);
const history = useHistory();
//Timeout to set variable after the fetch is done
useEffect(() => {
const timer = setTimeout(() => {
const planetDiameter = data.allPlanets.planets.map(
(planet) => planet.diameter
);
console.log(planetDiameter);
}, 500);
return () => clearTimeout(timer);
});
//Conditional for loading or error
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :</p>;
//Sort helper
const sortTypes = {
up: {
class: 'sort-up',
fn: (a, b) => a.planetDiameter - b.planetDiameter,
},
down: {
class: 'sort-down',
fn: (a, b) => b.planetDiameter - a.planetDiameter,
},
default: {
class: 'sort',
fn: (a, b) => a,
},
};
//Sort function
const onSortChange = () => {
let nextSort;
if (sortTable === 'down') nextSort = 'up';
else if (sortTable === 'up') nextSort = 'default';
else if (sortTable === 'default') nextSort = 'down';
setSortTable(nextSort);
};
return (
<div className='planets-container'>
<table className='table-fixed'>
<tbody>
<tr>
<th>Name</th>
<th className='cursor-pointer' onClick={() => onSortChange()}>
Size
<i className={`fas fa-${sortTypes[sortTable].class}`}></i>
</th>
<th>Population</th>
<th>Gravity</th>
</tr>
{data.allPlanets.planets
.sort(sortTypes[sortTable].fn)
.map((planet) => {
const handleRowClick = () => {
history.push(`/planet/${planet.name}`, { params: planet.id });
};
return (
<tr
className='border hover:bg-sky-700 border-slate-300 cursor-pointer'
onClick={() => handleRowClick()}
key={planet.id}
>
<td>{planet.name}</td>
<td>{planet.diameter}</td>
<td>{planet.population}</td>
<td>{planet.gravity}</td>
</tr>
);
})}
</tbody>
</table>
</div>
);
}
export default PlanetList;
See img where i'm getting the error: https://imgur.com/a/6JnF8mM https://imgur.com/a/omUtYb3
Nevermind, found the problem.
Needed a new array fort the sort function here.
{[...data.allPlanets.planets]
.sort(sortTypes[sortTable].fn)
.map((planet) => {
const handleRowClick = () => {
history.push(`/planet/${planet.name}`, { params: planet.id });
};
return (
<tr
className='border hover:bg-sky-700 border-slate-300 cursor-pointer'
onClick={() => handleRowClick()}
key={planet.id}
>
<td>{planet.name}</td>
<td>{planet.diameter}</td>
<td>{planet.population}</td>
<td>{planet.gravity}</td>
</tr>
);
})}
Here I was trying to sort the wrong stuff.
const sortTypes = {
up: {
class: 'sort-up',
fn: (a, b) => a.diameter - b.diameter,
},
down: {
class: 'sort-down',
fn: (a, b) => b.diameter - a.diameter,
},
default: {
class: 'sort',
fn: (a, b) => a,
},
};
Maybe it'll help somebody.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.