I am trying to upload an image to IPFS, which was selected by user in the front-end. I am storing the image in state hook and passing it on to the Form-data.
Following the pinata documentation I have also added the name of the file and pinata options in the form-data.
I am using axios to perform a get request to the Pinata server. The "handleFileUpload" function is used to deal with uploading the files to Pinata.
But I am getting a Bad-Request error (detailed error below) when I make the post request to the server.
Below I am providing my full code, this code is from one of my react components named create. My Full Code is provided below:
import { useState } from 'react';
import { Row, Form, Button } from 'react-bootstrap';
import { create as ipfsHttpClient } from 'ipfs-http-client';
import axios from 'axios';
import FormData from 'form-data';
const Create = ({ marketplace, nft }) => {
const [image, setImage] = useState();
const [price, setPrice] = useState(null);
const [name, setName] = useState('');
const [description, setDescription] = useState('');
let ImgHash;
const JWT = 'JWT_here'
const handleFileUpload = async(e) =>
{
e.preventDefault();
if(image)
{
const formData = new FormData();
formData.append("file", image[0]);
const pinataMetadata = JSON.stringify({
name: name,
});
formData.append('pinataMetadata', pinataMetadata);
const pinataOptions = JSON.stringify({
cidVersion: 0,
})
formData.append('pinataOptions', pinataOptions);
try
{
const res = await axios.post("https://api.pinata.cloud/pinning/pinFileToIPFS", formData,
{
maxBodyLength: "Infinity",
headers: {
'Content-Type': `multipart/form-data; boundary=${formData._boundary}`,
Authorization: JWT,
path: 'somename'
}
});
console.log(res.data);
ImgHash = `ipfs://${res.data.IpfsHash}`;
}
catch (error)
{
console.error('Error uploading file:', error);
}
}
}
return (
<div className="container-fluid mt-5">
<div className="row">
<main role="main" className="col-lg-12 mx-auto" style={{ maxWidth: '1000px' }}>
<div className="content mx-auto">
<Row className="g-4">
<Form.Control
type="file"
required
name="file"
onChange={(e) => setImage(e.target.files[0])}
/>
<Form.Control onChange={(e) => setName(e.target.value)} size="lg" required type="text" placeholder="Name" />
<Form.Control onChange={(e) => setDescription(e.target.value)} size="lg" required as="textarea" placeholder="Description" />
<Form.Control onChange={(e) => setPrice(e.target.value)} size="lg" required type="number" placeholder="Price in ETH" />
<div className="d-grid px-0">
<Button onClick={handleFileUpload} variant="primary" size="lg">
Create & List NFT!
</Button>
</div>
</Row>
</div>
</main>
</div>
</div>
);
}
export default Create
I tried going through the documentation to figure out the error, but could not figure out the exact cause.
Below are the Error Message I received when trying to make a post request:
AxiosError {message: 'Request failed with status code 400', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: {…}, request: XMLHttpRequest, …} code : "ERR_BAD_REQUEST" config : {transitional: {…}, adapter: Array(2), transformRequest: Array(1), transformResponse: Array(1), timeout: 0, …} message : "Request failed with status code 400" name : "AxiosError" request : XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …} response : {data: {…}, status: 400, statusText: '', headers: AxiosHeaders, config: {…}, …} stack : "AxiosError: Request failed with status code 400\n at settle (http://localhost:5173/node_modules/.vite/deps/axios.js?v=8be9dcc7:3371:12)\n at XMLHttpRequest.onloadend (http://localhost:5173/node_modules/.vite/deps/axios.js?v=8be9dcc7:3611:7)" [[Prototype]] : Error
400 status code indicates either endpoint is wrong or you are sending invalid or missing parameters in the request. But your endpoint url is correct, so probably you are setting wrong parameters. From docs
Example from docs