I'm trying to retrieve an array of data from an API, but during the application it receives an empty response. When I access this call in a swagger, it returns the correct array.
HomePage.tsx:
const HomePage = () => {
const books = useLoaderData();
console.log(books);
const bestOfMonthBooks = Array.isArray(books)
? books.filter((book) => !book.newRelease)
: [];
const newReleaseBooks = Array.isArray(books)
? books.filter((book) => book.newRelease)
: [];
return (
<>
<Carousel carouselData={DUUMY_CAROUSELITEMS} />
<Await resolve={books}>
<ListOfBooks books={bestOfMonthBooks} category="Best of month" />
<ListOfBooks books={newReleaseBooks} category="New releases" />
</Await>
</>
);
};
export default HomePage;
async function loadBooks() {
const response = await fetch("https://localhost:7276/GetAll");
if (!response.ok) {
throw new Error("Something went wrong");
} else {
const data = await response.json();
return data;
}
}
export function loader() {
return defer({
books: loadBooks,
});
}
BookRepository.cs:
List<Book> books = new List<Book>()
{
new Book(1,"public/assets/Books/book 1.jpg","Hero With Gold"," Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua","Dougie Rogers",90,false),
new Book(2,"pulbic/assets/Books/book 2.jpg","Goddes of Insanity","Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua","Dennis Jenkins",90, false),
new Book(3,"pulbic/assets/Books/book 3.jpg","Thieves Of The Lost World Of G","Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua","Quinn Holland",90, false),
new Book(4,"pulbic/assets/Books/book 4.jpg","Hunters Of Utopia","Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua","Cole Porter",90, false),
new Book(5,"pulbic/assets/Books/book 5.jpg","Lords And Gods","Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua","Elis Booth",90, false),
//new Book(6,"pulbic/assets/Books/book 6.jpg","Girls And Officers","Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua","Victor Miller",90, false),
new Book(7,"pulbic/assets/Books/book 7.jpg","Hero With Gold","Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua","Dougie Rogers",90, true),
new Book(8,"pulbic/assets/Books/book 8.jpg","Goddess Of Insanity","Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua","Dennis Jenkins",90, true),
new Book(9,"pulbic/assets/Books/book 9.jpg","Thieves Of The Lost World Of G","Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua","Quinn Holland",90, true),
new Book(10,"pulbic/assets/Books/book 10.jpg","Hunters Of Utopia","Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua","Cole Porter",90, true),
new Book(11,"pulbic/assets/Books/book 11.jpg","Lords And Gods","Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua","Elis Booth",90, true),
//new Book(12,"pulbic/assets/Books/book 12.jpg","Girls And Officers","Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua","Victor Miller",90, true),
};
public BookRepository()
{
}
public List<Book> GetAll()
{
return books;
}
object returned from loader:
books: async ƒ loadBooks()
length: 0
name: "loadBooks"
arguments: (...)
caller: (...)
[[FunctionLocation]]: HomePage.tsx:56
I tried to return to the loader in the bookmodel array and it still didn't work.
The loader
function doesn't return any data, it is just returning the loadBooks
function.
export function loader() { return defer({ books: loadBooks, // <-- function value returned! }); }
The HomePage
component is also missing about half the code it needs to correctly render deferred data loading.
See the Deferred Data guide for more details.
Update your loader
function to return the result of having called loadBooks
. In other words, actually invoke the loadBooks
function.
export function loader() {
return defer({
books: loadBooks()
});
}
Update Homepage
render a Suspense
component around Await
and provide Carousel
as the fallback UI while the data is fetched, and use a children render function to access the resolved deferred books
data.
import { Suspense } from "react";
import { Await, useLoaderData } from "react-router-dom";
const HomePage = () => {
const data = useLoaderData();
console.log({ data }); // <-- Promise object!
return (
<Suspense fallback={<Carousel carouselData={DUUMY_CAROUSELITEMS} />}>
<Await resolve={data.books}>
{(books) => {
console.log({ books }); // <-- books array response value
const bestOfMonthBooks = Array.isArray(books)
? books.filter((book) => !book.newRelease)
: [];
const newReleaseBooks = Array.isArray(books)
? books.filter((book) => book.newRelease)
: [];
return (
<>
<ListOfBooks
books={bestOfMonthBooks}
category="Best of month"
/>
<ListOfBooks books={newReleaseBooks} category="New releases" />
</>
);
}}
</Await>
</Suspense>
);
};