0

i cannot sort an array in React. Im fetching data like this:

function AllMeetupsPage() {
  const [isLoading, setIsLoading] = useState(true);
  const [loadedMeetups, setLoadedMeetups] = useState([]);

  useEffect(() => {
    setIsLoading(true);
    fetch("https://reacttesty-2fbdf-default-rtdb.firebaseio.com/api/book.json")
      .then((response) => {
        return response.json();
      })
      .then((data) => {
        const meetups = [];

        for (const key in data) {
          const meetup = {
            id: key,
            ...data[key],
          };

          meetups.push(meetup);
        }

        setIsLoading(false);
        setLoadedMeetups(meetups);
      });
  }, []);

And then i want to render it. Here im trying to sort loadedMeetups, i tried several diffrent thing but it don't work. F.e simple loadedMeetups.reverse() works fine.

return (
    <section>
      <h1>All Meetups</h1>
      <MeetupList meetups={loadedMeetups.sort(
        (a, b) => b['title'] - a['title']
      )} />   {/* Here im trying to sort loadedMeetups, i tried several diffrent thing but it don't work.
       F.e simple loadedMeetups.reverse() works fine.*/}
      <button onClick={handleClick}></button>
    </section>
  );
}

It don't work.

Here is the object console.log in browser

0:
author: "Lewis Carroll"
description: "Alicja w Krainie Czarów to powieść napisana przez Carroll'a"
genre: "Powieść"
id: "-MbN_UVuJJvfCjonq6E1"
image_url: "https://cdn.bonito.pl/zdjecia/7/8723-alicja-w-krainie-czarow.jpg"
release_date: " 2000-12-31"
title: "Alicja w Krainie Czarów"
__proto__: Object
1:
author: "J.K Rowling "
description: "Książka o czarodzieju"
genre: "Fantastyka"
id: "-MbNbGx4MlJY5VafwuzN"
image_url: "https://cdn-lubimyczytac.pl/upload/books/308000/308630/494238-352x500.jpg"
release_date: "2002-08-20"
title: "Harry Potte

I know that the problem is somewhere in fetching the data, because i tried to sort it on some dummy_data array i created on my own and it works. But i am not very familiar with fetch and currently dont really understand it, i just had to use it to connect to the api.

0

2 Answers 2

0

If you want to sort the items by title, you could use localeCompare

const books = [{
    author: "Lewis Carroll",
    description: "Alicja w Krainie Czarów to powieść napisana przez Carroll'a",
    genre: "Powieść",
    id: "-MbN_UVuJJvfCjonq6E1",
    image_url: "https://cdn.bonito.pl/zdjecia/7/8723-alicja-w-krainie-czarow.jpg",
    release_date: " 2000-12-31",
    title: "Alicja w Krainie Czarów",
  },
  {
    author: "J.K Rowling ",
    description: "Książka o czarodzieju",
    genre: "Fantastyka",
    id: "-MbNbGx4MlJY5VafwuzN",
    image_url: "https://cdn-lubimyczytac.pl/upload/books/308000/308630/494238-352x500.jpg",
    release_date: "2002-08-20",
    title: "Harry Potte",
  },
  {
    author: "J.K Rowling ",
    description: "Książka o czarodzieju",
    genre: "Fantastyka",
    id: "-MbNbGx4MlJY5VafwuzN",
    image_url: "https://cdn-lubimyczytac.pl/upload/books/308000/308630/494238-352x500.jpg",
    release_date: "2002-08-20",
    title: "Barry Potte",
  }
]

const sorted = books.sort((a,b) => a.title.localeCompare(b.title));

console.log(sorted);

Also, if your data comes in as an array, you don't need a conversion, you could just set the state to the response (except if you want to change the data which could be the case).

useEffect(() => {
  setIsLoading(true);
  fetch("https://reacttesty-2fbdf-default-rtdb.firebaseio.com/api/book.json")
    .then((response) => response.json())
    .then((data) => {
      setIsLoading(false);
      setLoadedMeetups(data);
    });
}, []);
Sign up to request clarification or add additional context in comments.

Comments

0

Try this.

The API response is actually two objects nested in an object.

{
   {},
   {}
}

So you need to extract the keys and map through to get the objects into an array. Then perform the sorting.

I would perform the sorting in the useEffect hook so that the sorting doesn't happen every re-render (which is currently happening in the given code).

  const [isLoading, setIsLoading] = useState(false);
  const [loadedMeetups, setLoadedMeetups] = useState([]);

  useEffect(() => {
    setIsLoading(true);

    fetch("https://reacttesty-2fbdf-default-rtdb.firebaseio.com/api/book.json")
      .then((res) => res.json())
      .then((data) => {
        const meetings = Object.keys(data)
          .map((key) => data[key])
          .sort((a, b) => a.author.localeCompare(b.author));
        setLoadedMeetups(meetings);
        setIsLoading(false);
      });
  }, []);

  return (
    <section>
      <h1>All Meetups</h1>
      {!isLoading && loadedMeetups.length > 0 && (
        <ul>
          {loadedMeetups.map((meetup) => (
            <li key={meetup.description}>
              {meetup.author} - {meetup.description}
            </li>
          ))}
        </ul>
      )}
    </section>
  );

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.