Struggling to successfully upload a file to the Strapi upload API from a Next.js API route

Currently, I have implemented react dropzone on a specific page for the purpose of sending a file to an API route called /api/upload. Afterward, the file is supposed to be uploaded to a Strapi upload API using the following code:

import formidable from 'formidable';
var FormData = require('form-data');
const fs = require('fs');

export default async function handler(req, res) {
  const {cookies: {jwt}, query: {user_id}} = req
  
  if (req.method === 'POST') {

    const form = new formidable.IncomingForm();


    const submittedFormData = await new Promise((resolve, reject) => {
      form.parse(req, (err, fields, files) => {
        if (err) {
          reject(err);
        } else {
          resolve({ fields, files });
        }
      });
    });

    const { fields, files } = submittedFormData;

    if(Object.keys(fields).length){
      const resp = await fetch(`${process.env.NEXT_PUBLIC_BACKEND_URL}/api/users/${user_id}`,{
        method: "PUT",
        headers: {
            Authorization: `Bearer ${jwt}`,
            "Content-Type": "application/json"
        },
        body: JSON.stringify(fields)
    })

    const data = await resp.json()

    console.log('Fields data',data);
    }

    if(files.files){
      console.log('There are files in there',`${process.env.NEXT_PUBLIC_API_URL}/upload`, req.headers["content-type"],);
      const fileStream = fs.createReadStream(files.files.filepath);

      const formData = new FormData();
      formData.append('files', fileStream, files.files.originalFilename);
      formData.append('ref', 'plugin::users-permissions.user')
      formData.append('refId', user_id)
      formData.append('field', 'profile_picture')


      const imageResp = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/upload`,{
        method: "POST",
        headers: {
            Authorization: `Bearer ${jwt}`
        },
        body: formData
    })

      const imageData = await imageResp.json()

      console.log('imageData',imageResp, imageData);
      
    }

    res.status(200).json({ fields, files });



  } else {
    res.status(405).json({ error: 'Method not allowed' });
  }
}

export const config = {
  api: {
    bodyParser: false,
  },
};

Despite this implementation, I keep encountering an error message from Strapi:

{
  data: null,
  error: {
    status: 400,
    name: 'ValidationError',
    message: 'Files are empty',
    details: {}
  }
}

I've been troubleshooting this issue for the past couple of weeks without any success. What could possibly be going wrong with my current setup?

Answer №1

Hey there, it seems like there may be a misunderstanding in the pipeline process.

To upload files, you should utilize the api/upload route and use FormData to upload the files. Upon uploading, you will receive an object containing the [{id}] of the uploaded files.

The api/contentType/ route requires the [{id}] to be included with the provided data.

Here's an example:

// Omitting error handling for brevity

let formData = new FormData();
files.forEach(file => formData.append('files', file));

const { data:media } = await fetch('api/upload', { body: formData, method: 'POST', headers: ... }).then(res => res.json());


// Update user entry 
const data = { 
    title: 'idk',
    media // This is an array of objects with a mandatory `id` property 
 }

const entry = await fetch(`api/user/${userId}`, { method: 'PUT', body: JSON.stringify({...data}) }, headers: ... })

Keep in mind that for regular api routes, you need to specify body: { data }, and for user permissions, include body: {...data }.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The size of Next.js builds is steadily increasing

After creating a new nextjs project using app routes, I noticed that when I run npm run build, the .next folder ends up being approximately 32mb in size. I'm curious to know if this is a typical size for a nextjs project. During development, I watche ...

Implementing basic authentication for an Express REST API

I have a REST API where user data is stored in MongoDB. I am looking to implement basic authentication for my API, but I am facing some challenges. I want to check if a user is authorized on certain paths, such as /update. If the user is authorized, the re ...

Exploring the best way to use $set in Mongoose for dynamically updating an embedded

I'm currently attempting to create a unique function that can update the value of a specific embedded MongoDB document within an array. The goal is to change the value based on its position. function removeAddress(accountNum, pos) { const remove ...

promise-sftp freezing after completing 'put' operation

I am currently developing a NodeJS module that uploads files to an SFTP server using version 0.11.3 of promise-sftp. Here is a summary of the steps I am taking: const PromiseFtp = require('promise-sftp'); const ftp = new PromiseFtp(); await ftp.c ...

It appears that React is rendering all elements, but only the first one is being shown

I am currently working on a component: const StudentName = (student) => ( <div key={student.engName} test={console.log("Name: "+student.val().engName)}> <Typography className={ student==currentStudent ? 's ...

Setting up Next.js 13 with GraphQL and Apollo Configuration

I am currently working on configuring a graphql frontend application with nextjs13. However, I have encountered an issue with the new folder structure as there is no longer an _app.tsx file. I am now unsure of how to proceed with setting it up. Previously ...

To combine arrays A and B within a React useState object, simply pass them as arguments when initializing the state

Currently, I am working on integrating infinite scroll functionality in React, where I need to fetch data from a backend API for loading content on the next page. The challenge I'm facing is that my state is set as an object using useState, and I need ...

Error encountered in MDAVSCLI: EPERM, operation not allowed on 'C:WindowsCSCv2.0.6'

After successfully installing VS tools for Cordova on VS2013 with all default settings, I encountered a node error while attempting to build and run the default "BlankCordovaApp" template. 1>MDAVSCLI : error : EPERM, operation not permitted 'C:&b ...

How can I change the nested Material UI component style from its parent component?

I am currently incorporating a component from an external library into my project. However, I am facing limitations in customizing its style, especially when it comes to a button that is using material ui styles. Upon inspecting the element, I can see that ...

Getting a Next.js error after performing a hard refresh on a page that contains a dynamic query

I have encountered an issue with my Next.js app when I attempt to hard reload it in production mode. The error message I receive is 404 - File or directory not found. Below is the code snippet I am using: import { useRouter } from "next/router"; import ...

The Angular project encounters a failure when attempting to run 'ng serve,' resulting in an emitted 'error' event on the worker

Resolved Issue - Update: It appears that the problem was due to an error in my CSS code: Previous: .title & .smaller { color: $dark-blue; font-family: "Roboto"; font-size: 20px; font-weight: 600; width: fit-content; margin: 0; ...

The error message states that Next JS is having trouble accessing properties related to headers due to being undefined

Utilizing the Django rest framework on the backend is my current setup. Whenever a user inputs incorrect credentials, I send a 400 status from the backend. As for the frontend, I have opted for NEXT.js. An issue arises in the signin process within the rout ...

Finding the complete file path in layout.js for NextJS version 13 within the app directory

My goal is to fetch the URL /events/345/edit from within the layout.js file. I am looking to show a "page name" title on each individual page.js, but in order to accomplish this, I require knowledge of my current location within the layout.js file. ap ...

Material UI and Next JS do not cooperate well with styles

Help! The global styles are taking over my custom ones. I'm working with Material UI in Next.js. ...

Clickable rows with MUI table icon buttons that enhance user interaction

Make the table rows clickable: <TableRow sx={{ '&.MuiTableRow-root': { cursor: 'pointer' } }} hover key={row.id} onClick={() => handleRowClick(row.id)} > An icon button is present in one column: <TableCell> ...

NextJS introduces a unique functionality to Typescript's non-null assertion behavior

As per the typescript definition, the use of the non-null assertion operator is not supposed to impact execution. However, I have encountered a scenario where it does. I have been struggling to replicate this issue in a simpler project. In my current proj ...

Error: npm global installation not detected for gulp

My first attempt at using gulp has hit a roadblock. Despite following online instructions, I encountered the error message 'gulp' is not recognized as an internal or external command[...] after installing it both globally and locally. Switching ...

What is the best way to retrieve data in my client component without risking exposing my API key to unauthorized users?

To retrieve information, I plan to use pagination in order to specify a particular page number within the API URL and fetch additional data by updating the value of page. The process of fetching data in my server component is as follows: // fetchData.tsx ...

Error message: "Supabase connection is returning an undefined value

I am encountering an issue with my Vercel deployed Remix project that utilizes Supabase on the backend, Postgresql, and Prisma as the ORM. Despite setting up connection pooling and a direct connection to Supabase, I keep receiving the following error whene ...

Calling Node Express request inside a GET route

I am currently utilizing nodejs as an intermediary layer between my public website and an internal server within our network. Through the use of express.js, I have created a basic REST api where the endpoint should trigger a request call to a webservice a ...