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

0

There are 0 best solutions below