简体   繁体   中英

Sort table with data dom graphQL

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM