I’m new to programming, and I’ve been facing some difficulties creating a download button in my React file. In short, I’ve built an API with Kotlin Spring Boot and tested it with JSON. Now, I’m trying to consume this API with React.
My difficulty is with the download feature. The button downloads the file, but it appears empty. However, when I inspect the element, the file appears in the ‘source console’ (Safari) with all its content, allowing me to save it.
Can you help me clarify why the download button does not show the PDF content? What can I do to solve this?
More information on my GitHub: https://github.com/raysatownsend/Consumindo_Api_React/blob/main/src/pages/Books/index.js
thank you!
Expect a help with my code instruction. It may be wrong.
My code is below:
export default function Books() {
const [books, setBooks] = useState([]);
const [page, setPage] = useState(0);
const [files, setFiles] = useState([]);
const navigate = useNavigate();
const accessToken = localStorage.getItem("accessToken");
const username = localStorage.getItem("username");
const authorization = {
headers:{
Authorization: `Bearer ${accessToken}`
}
};
const contentType = {
headers: {
"Content-Type": "application/octet-stream",
"Content-Type": "application/pdf"
}
}
const responseType = {
headers: {
responseType: 'blob',
}
}
useEffect(() => {
fetchMoreBooks();
}, [accessToken])
async function fetchMoreBooks() {
const response = await api.get(`api/books/v1?page=${page}&size=8&direction=asc`, authorization)
setBooks([...books, ...response.data._embedded.authorVOList]);
setPage(page + 1);
}
async function editBook(id) {
try {
navigate(`/books/book/new/${id}`);
} catch (error) {
alert("Edit book failed, please try again.")
}
}
async function downloadBook() {
try {
const response = await api.get("api/file/v1/downloadFile/PRESSMAN_Engenharia_de_software_Uma_Abor.pdf", authorization, contentType, responseType)
// Create a Blob object from the response data
const blob = new Blob([...files, ...response.data], { type: response.headers["Content-Type"] });
// Create a temporary anchor element
const downloadLink = document.createElement('a');
downloadLink.href = window.URL.createObjectURL(blob);
downloadLink.setAttribute('download', 'PRESSMAN_Engenharia_de_software_Uma_Abor.pdf'); // Set the download attribute with desired filename
document.body.appendChild(downloadLink);
// Trigger the download by programmatically clicking the anchor element
downloadLink.click();
// Cleanup
window.URL.revokeObjectURL(downloadLink.href);
} catch (error) {
alert("ERROR: Can't download choosen item, please try again.");
}
}
async function deleteBook(id) {
try {
await api.delete(`api/books/v1/${id}`, authorization)
setBooks(books.filter(book => book.id !== id))
} catch (error) {
alert("ERROR: Can't delete choosen item, please try again.")
}
}
async function logout() {
try {
localStorage.clear()
navigate("/")
} catch (error) {
alert("Logout failed, please try again.")
}
}
return (
<div className="book-container">
<header>
<img src={logoImage} alt="Logo" />
<span>Bem-Vindo, <strong>{username.toUpperCase()}</strong>!</span>
<Link className="button" to="book/new/0">Add New Book</Link>
<button onClick={logout} type="button">
<FiPower size={18} color='#251FC5'/>
</button>
</header>
<h1>Registered Books</h1>
<ul>
{books.map(book => (
<li key={book.id}>
<strong>Title:</strong>
<p>{book.title}</p>
<strong>Author:</strong>
<p>{book.author}</p>
<strong>Price:</strong>
<p>{Intl.NumberFormat('pt-BR', {style: 'currency', currency: 'BRL'}).format(book.price)}</p>
<strong>Release Date:</strong>
<p>{Intl.DateTimeFormat('pt-BR').format(new Date(book.launchDate))}</p>
<button onClick={() => editBook(book.id)} type="button">
<FiEdit size={20} color="#251FC5"/>
</button>
<button onClick={() => downloadBook()} type="button">
<FiDownload size={20} color="#251FC5"/>
</button>
<button onClick={() => deleteBook(book.id)} type="button">
<FiTrash2 size={20} color="#251FC5"/>
</button>
</li>
))}
</ul>
<button className="button" onClick={fetchMoreBooks} type="button">Load more</button>
</div>
);
}
Raysa Townsend Carraro is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.