Error: data: '{"status":false,"message":"ctx.ShouldBind(\u0026param) : unsupported field type for multipart.FileHeader"}'
Next Api Route Handler
Here is my api route implementation for the upload files
/api/trackupload.ts
import axios from 'axios';
import type { NextApiRequest, NextApiResponse } from 'next';
export const config = {
api: {
bodyParser: false,
},
};
export default async function handler(
req: NextApiRequest,
res: NextApiResponse,
) {
if (req.method === 'POST') {
try {
const requestData = req;
const token = req.cookies.authToken;
const { data }: any = await axios({
url: `${process.env.NEXT_PUBLIC_BASEURL}/artists/uploads/new`,
method: 'POST',
data: requestData,
responseType: 'blob',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': req.headers['content-type'],
},
});
if (data) {res.status(201).json({ message: 'Song uploaded successfully', data });
} else {
res.status(400).json({ error: 'upload failed' });
}
} catch (err: any) {
console.error(err);
if (err.response && err.response.status === 502) {
res.status(520).json({ error: 'Bad Gateway' });
} else {
res.status(500).json({ error: 'Internal server error' });
}
}
} else {
res.status(405).json({ error: 'Method not allowed' });
}
}
Frontend Implementation**
/pages/uploadTest.tsx
Here I used Formik to collect data from the Form
interface FormValues {
upload_title: string;
upload_type: string;
upload_image?: File | any;
upload_genre: string;
upload_release_date: string;
upload_privacy: string;
is_playlisted: boolean;
has_explicit_content: boolean;
songs: {
track_name: string;
features?: string;
producer?: string;
writer?: string;
lyrics?: string;
genre: string;
}[];
}
const uploadTest = () => {
This is where handled the array of information to prevent repetition of field values
const handleSongChange = (
index: any,
fieldName: string,
value: any,
setFieldValue: any,
) => {
setFieldValue(`songs[${index}].${fieldName}`, value);
};
const handleSubmit = async (e: any) => {
e.preventDefault();
if (!uploadFiles && !uploadImage) {
console.log('select a file');
} else {
const formData: any = new FormData();
To put all of the information I want to upload in an array
const combinedData = values.songs.map((song, index) => {
return {
...song,
track: uploadFiles[index],
};
});
combinedData.forEach((song) => {
formData.append('track_name', song.track_name);
formData.append('featured_artists', song.features);
formData.append('producer', song.producer);
formData.append('song_writer', song.writer);
formData.append('lyrics', song.lyrics);
formData.append('genre', song.genre);
});
combinedData.forEach((song) => {
formData.append('track', song.track)
});
append other information
formData.append('upload_title', values.upload_title);
formData.append('upload_type', values.upload_type);
formData.append('upload_image', uploadImage);
formData.append('upload_privacy', values.upload_privacy);
formData.append('is_playlisted', values.is_playlisted);
formData.append('has_explicit_content', values.has_explicit_content);
formData.append('upload_release_date', values.upload_release_date);
combinedData.forEach((comb: any) => {
for (const key in comb) {
if (comb.hasOwnProperty(key)) {
formData.append('songs', comb[key]);
}
}
});
try {
const response = await axios.post('/api/trackUpload', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
console.log(response);
} catch (err) {
console.log(err);
}
console.log(uploadFiles);
console.log(combinedData);
}
};
const { values, handleChange, setFieldValue } = useFormik<FormValues>({
initialValues: {
upload_title: '',
upload_type: '',
upload_image: '',
upload_genre: '',
upload_release_date: '',
upload_privacy: '',
is_playlisted: false,
has_explicit_content: false,
songs: [
{
track_name: '',
features: '',
producer: '',
writer: '',
lyrics: '',
genre: '',
},
],
},
onSubmit: handleSubmit,
});
const [uploadFiles, setUploadFiles] = useState<File | any>([]);
const [uploadImage, setUploadImage] = useState<File | any>([]);
const handleTrackChange = (e: any) => {
const trackFile: FileList | null = e.target.files;
if (trackFile) {
const trackFileArray = Array.from(trackFile);
setUploadFiles((prevTrack: any) => [...prevTrack, ...trackFileArray]);
}
};
const handleImageChange = (e: any) => {
const imageFile = e.target.files[0];
setUploadImage(imageFile);
};
Please refer to the image below to understand the data model Data model structure imageGo Data model structure image